Merge "Make MP2 operations asynchronous and send matching notifications" into pi-dev

am: 2b83982b2b

Change-Id: I4ad98268bcd594ca39a3d08824c845e339f73741
This commit is contained in:
Dongwon Kang
2018-03-13 01:05:08 +00:00
committed by android-build-merger
4 changed files with 611 additions and 355 deletions

View File

@@ -24351,7 +24351,6 @@ package android.media {
method public abstract android.media.MediaDrm.KeyRequest getDrmKeyRequest(byte[], byte[], java.lang.String, int, java.util.Map<java.lang.String, java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
method public abstract java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer2.NoDrmSchemeException;
method public abstract long getDuration();
method public abstract int getMediaPlayer2State();
method public abstract android.os.PersistableBundle getMetrics();
method public abstract android.media.PlaybackParams getPlaybackParams();
method public abstract int getSelectedTrack(int);
@@ -24377,33 +24376,35 @@ package android.media {
method public abstract void setPlaybackParams(android.media.PlaybackParams);
method public abstract void setSurface(android.view.Surface);
method public abstract void setSyncParams(android.media.SyncParams);
field public static final int MEDIAPLAYER2_STATE_ERROR = 5; // 0x5
field public static final int MEDIAPLAYER2_STATE_IDLE = 1; // 0x1
field public static final int MEDIAPLAYER2_STATE_PAUSED = 3; // 0x3
field public static final int MEDIAPLAYER2_STATE_PLAYING = 4; // 0x4
field public static final int MEDIAPLAYER2_STATE_PREPARED = 2; // 0x2
field public static final int MEDIA_CALL_ATTACH_AUX_EFFECT = 1; // 0x1
field public static final int MEDIA_CALL_DESELECT_TRACK = 2; // 0x2
field public static final int MEDIA_CALL_LOOP_CURRENT = 3; // 0x3
field public static final int MEDIA_CALL_PAUSE = 4; // 0x4
field public static final int MEDIA_CALL_PLAY = 5; // 0x5
field public static final int MEDIA_CALL_PREPARE = 6; // 0x6
field public static final int MEDIA_CALL_RELEASE_DRM = 12; // 0xc
field public static final int MEDIA_CALL_RESTORE_DRM_KEYS = 13; // 0xd
field public static final int MEDIA_CALL_SEEK_TO = 14; // 0xe
field public static final int MEDIA_CALL_SELECT_TRACK = 15; // 0xf
field public static final int MEDIA_CALL_SET_AUDIO_ATTRIBUTES = 16; // 0x10
field public static final int MEDIA_CALL_SET_AUDIO_SESSION_ID = 17; // 0x11
field public static final int MEDIA_CALL_SET_AUX_EFFECT_SEND_LEVEL = 18; // 0x12
field public static final int MEDIA_CALL_SET_DATA_SOURCE = 19; // 0x13
field public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCE = 22; // 0x16
field public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCES = 23; // 0x17
field public static final int MEDIA_CALL_SET_PLAYBACK_PARAMS = 24; // 0x18
field public static final int MEDIA_CALL_SET_PLAYBACK_SPEED = 25; // 0x19
field public static final int MEDIA_CALL_SET_PLAYER_VOLUME = 26; // 0x1a
field public static final int MEDIA_CALL_SET_SURFACE = 27; // 0x1b
field public static final int MEDIA_CALL_SET_SYNC_PARAMS = 28; // 0x1c
field public static final int MEDIA_CALL_SKIP_TO_NEXT = 29; // 0x1d
field public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1; // 0x1
field public static final int CALL_COMPLETED_DESELECT_TRACK = 2; // 0x2
field public static final int CALL_COMPLETED_LOOP_CURRENT = 3; // 0x3
field public static final int CALL_COMPLETED_PAUSE = 4; // 0x4
field public static final int CALL_COMPLETED_PLAY = 5; // 0x5
field public static final int CALL_COMPLETED_PREPARE = 6; // 0x6
field public static final int CALL_COMPLETED_RELEASE_DRM = 12; // 0xc
field public static final int CALL_COMPLETED_RESTORE_DRM_KEYS = 13; // 0xd
field public static final int CALL_COMPLETED_SEEK_TO = 14; // 0xe
field public static final int CALL_COMPLETED_SELECT_TRACK = 15; // 0xf
field public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16; // 0x10
field public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17; // 0x11
field public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18; // 0x12
field public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19; // 0x13
field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22; // 0x16
field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23; // 0x17
field public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24; // 0x18
field public static final int CALL_COMPLETED_SET_PLAYBACK_SPEED = 25; // 0x19
field public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26; // 0x1a
field public static final int CALL_COMPLETED_SET_SURFACE = 27; // 0x1b
field public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28; // 0x1c
field public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29; // 0x1d
field public static final int CALL_STATUS_BAD_VALUE = 2; // 0x2
field public static final int CALL_STATUS_ERROR_IO = 4; // 0x4
field public static final int CALL_STATUS_ERROR_UNKNOWN = -2147483648; // 0x80000000
field public static final int CALL_STATUS_INVALID_OPERATION = 1; // 0x1
field public static final int CALL_STATUS_NO_DRM_SCHEME = 5; // 0x5
field public static final int CALL_STATUS_NO_ERROR = 0; // 0x0
field public static final int CALL_STATUS_PERMISSION_DENIED = 3; // 0x3
field public static final int MEDIA_ERROR_IO = -1004; // 0xfffffc14
field public static final int MEDIA_ERROR_MALFORMED = -1007; // 0xfffffc11
field public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200; // 0xc8
@@ -24453,7 +24454,7 @@ package android.media {
public static abstract class MediaPlayer2.MediaPlayer2EventCallback {
ctor public MediaPlayer2.MediaPlayer2EventCallback();
method public void onCallComplete(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
method public void onCallCompleted(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
method public void onCommandLabelReached(android.media.MediaPlayer2, java.lang.Object);
method public void onError(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
method public void onInfo(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);

View File

@@ -214,7 +214,8 @@ import java.util.concurrent.Executor;
* call returns right away, the actual seek operation may take a while to
* finish, especially for audio/video being streamed. When the actual
* seek operation completes, the internal player engine calls a user
* supplied MediaPlayer2EventCallback.onCallComplete() with {@link #MEDIA_CALL_SEEK_TO}
* supplied MediaPlayer2EventCallback.onCallCompleted() with
* {@link #CALL_COMPLETED_SEEK_TO}
* if an MediaPlayer2EventCallback has been registered beforehand via
* {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
* <li>Please
@@ -819,7 +820,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* of a batch of commands.
*/
// This is an asynchronous call.
public void notifyWhenCommandLabelReached(Object label) { }
public void notifyWhenCommandLabelReached(@NonNull Object label) { }
/**
* Sets the {@link SurfaceHolder} to use for displaying the video
@@ -1051,6 +1052,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
/**
* MediaPlayer2 has not been prepared or just has been reset.
* In this state, MediaPlayer2 doesn't fetch data.
* @hide
*/
public static final int MEDIAPLAYER2_STATE_IDLE = 1;
@@ -1058,29 +1060,33 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* MediaPlayer2 has been just prepared.
* In this state, MediaPlayer2 just fetches data from media source,
* but doesn't actively render data.
* @hide
*/
public static final int MEDIAPLAYER2_STATE_PREPARED = 2;
/**
* MediaPlayer2 is paused.
* In this state, MediaPlayer2 doesn't actively render data.
* @hide
*/
public static final int MEDIAPLAYER2_STATE_PAUSED = 3;
/**
* MediaPlayer2 is actively playing back data.
* @hide
*/
public static final int MEDIAPLAYER2_STATE_PLAYING = 4;
/**
* MediaPlayer2 has hit some fatal error and cannot continue playback.
* @hide
*/
public static final int MEDIAPLAYER2_STATE_ERROR = 5;
/**
* @hide
*/
@IntDef({
@IntDef(flag = false, prefix = "MEDIAPLAYER2_STATE", value = {
MEDIAPLAYER2_STATE_IDLE,
MEDIAPLAYER2_STATE_PREPARED,
MEDIAPLAYER2_STATE_PAUSED,
@@ -1093,6 +1099,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* Gets the current MediaPlayer2 state.
*
* @return the current MediaPlayer2 state.
* @hide
*/
public abstract @MediaPlayer2State int getMediaPlayer2State();
@@ -1170,8 +1177,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
/** @hide */
@IntDef(
value = {
@IntDef(flag = false, prefix = "PLAYBACK_RATE_AUDIO_MODE", value = {
PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
PLAYBACK_RATE_AUDIO_MODE_STRETCH,
PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
@@ -1276,8 +1282,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
public static final int SEEK_CLOSEST = 0x03;
/** @hide */
@IntDef(
value = {
@IntDef(flag = false, prefix = "SEEK", value = {
SEEK_PREVIOUS_SYNC,
SEEK_NEXT_SYNC,
SEEK_CLOSEST_SYNC,
@@ -1302,16 +1307,6 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* If msec is negative, time position zero will be used.
* If msec is larger than duration, duration will be used.
* @param mode the mode indicating where exactly to seek to.
* Use {@link #SEEK_PREVIOUS_SYNC} if one wants to seek to a sync frame
* that has a timestamp earlier than or the same as msec. Use
* {@link #SEEK_NEXT_SYNC} if one wants to seek to a sync frame
* that has a timestamp later than or the same as msec. Use
* {@link #SEEK_CLOSEST_SYNC} if one wants to seek to a sync frame
* that has a timestamp closest to or the same as msec. Use
* {@link #SEEK_CLOSEST} if one wants to seek to a frame that may
* or may not be a sync frame but is closest to or the same as msec.
* {@link #SEEK_CLOSEST} often has larger performance overhead compared
* to the other options if there is no sync frame located at msec.
*/
// This is an asynchronous call.
public abstract void seekTo(long msec, @SeekMode int mode);
@@ -1753,28 +1748,20 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* @param dsd the DataSourceDesc of this data source
* @param data the timed metadata sample associated with this event
*/
public void onTimedMetaDataAvailable(MediaPlayer2 mp, DataSourceDesc dsd, TimedMetaData data) { }
public void onTimedMetaDataAvailable(
MediaPlayer2 mp, DataSourceDesc dsd, TimedMetaData data) { }
/**
* Called to indicate an error.
*
* @param mp the MediaPlayer2 the error pertains to
* @param dsd the DataSourceDesc of this data source
* @param what the type of error that has occurred:
* <ul>
* <li>{@link #MEDIA_ERROR_UNKNOWN}
* </ul>
* @param what the type of error that has occurred.
* @param extra an extra code, specific to the error. Typically
* implementation dependent.
* <ul>
* <li>{@link #MEDIA_ERROR_IO}
* <li>{@link #MEDIA_ERROR_MALFORMED}
* <li>{@link #MEDIA_ERROR_UNSUPPORTED}
* <li>{@link #MEDIA_ERROR_TIMED_OUT}
* <li><code>MEDIA_ERROR_SYSTEM (-2147483648)</code> - low-level system error.
* </ul>
*/
public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) { }
public void onError(
MediaPlayer2 mp, DataSourceDesc dsd, @MediaError int what, int extra) { }
/**
* Called to indicate an info or a warning.
@@ -1782,29 +1769,10 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* @param mp the MediaPlayer2 the info pertains to.
* @param dsd the DataSourceDesc of this data source
* @param what the type of info or warning.
* <ul>
* <li>{@link #MEDIA_INFO_UNKNOWN}
* <li>{@link #MEDIA_INFO_STARTED_AS_NEXT}
* <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}
* <li>{@link #MEDIA_INFO_AUDIO_RENDERING_START}
* <li>{@link #MEDIA_INFO_PLAYBACK_COMPLETE}
* <li>{@link #MEDIA_INFO_PLAYLIST_END}
* <li>{@link #MEDIA_INFO_PREPARED}
* <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}
* <li>{@link #MEDIA_INFO_BUFFERING_START}
* <li>{@link #MEDIA_INFO_BUFFERING_END}
* <li><code>MEDIA_INFO_NETWORK_BANDWIDTH (703)</code> -
* bandwidth information is available (as <code>extra</code> kbps)
* <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
* <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
* <li>{@link #MEDIA_INFO_METADATA_UPDATE}
* <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
* <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
* </ul>
* @param extra an extra code, specific to the info. Typically
* implementation dependent.
*/
public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) { }
public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, @MediaInfo int what, int extra) { }
/**
* Called to acknowledge an API call.
@@ -1812,33 +1780,11 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* @param mp the MediaPlayer2 the call was made on.
* @param dsd the DataSourceDesc of this data source
* @param what the enum for the API call.
* <ul>
* <li>{@link #MEDIA_CALL_ATTACH_AUX_EFFECT}
* <li>{@link #MEDIA_CALL_DESELECT_TRACK}
* <li>{@link #MEDIA_CALL_LOOP_CURRENT}
* <li>{@link #MEDIA_CALL_PAUSE}
* <li>{@link #MEDIA_CALL_PLAY}
* <li>{@link #MEDIA_CALL_PREPARE}
* <li>{@link #MEDIA_CALL_RELEASE_DRM}
* <li>{@link #MEDIA_CALL_RESTORE_DRM_KEYS}
* <li>{@link #MEDIA_CALL_SEEK_TO}
* <li>{@link #MEDIA_CALL_SELECT_TRACK}
* <li>{@link #MEDIA_CALL_SET_AUDIO_ATTRIBUTES}
* <li>{@link #MEDIA_CALL_SET_AUDIO_SESSION_ID}
* <li>{@link #MEDIA_CALL_SET_AUX_EFFECT_SEND_LEVEL}
* <li>{@link #MEDIA_CALL_SET_DATA_SOURCE}
* <li>{@link #MEDIA_CALL_SET_NEXT_DATA_SOURCE}
* <li>{@link #MEDIA_CALL_SET_NEXT_DATA_SOURCES}
* <li>{@link #MEDIA_CALL_SET_PLAYBACK_PARAMS}
* <li>{@link #MEDIA_CALL_SET_PLAYBACK_SPEED}
* <li>{@link #MEDIA_CALL_SET_PLAYER_VOLUME}
* <li>{@link #MEDIA_CALL_SET_SURFACE}
* <li>{@link #MEDIA_CALL_SET_SYNC_PARAMS}
* <li>{@link #MEDIA_CALL_SKIP_TO_NEXT}
* </ul>
* @param status the returned status code for the call.
*/
public void onCallComplete(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) { }
public void onCallCompleted(
MediaPlayer2 mp, DataSourceDesc dsd, @CallCompleted int what,
@CallStatus int status) { }
/**
* Called to indicate media clock has changed.
@@ -1847,7 +1793,8 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* @param dsd the DataSourceDesc of this data source
* @param timestamp the new media clock.
*/
public void onMediaTimeChanged(MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) { }
public void onMediaTimeChanged(
MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) { }
/**
* Called to indicate {@link #notifyWhenCommandLabelReached(Object)} has been processed.
@@ -1856,7 +1803,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
* @param label the application specific Object given by
* {@link #notifyWhenCommandLabelReached(Object)}.
*/
public void onCommandLabelReached(MediaPlayer2 mp, Object label) { }
public void onCommandLabelReached(MediaPlayer2 mp, @NonNull Object label) { }
}
/**
@@ -1929,6 +1876,20 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
*/
public static final int MEDIA_ERROR_SYSTEM = -2147483648;
/**
* @hide
*/
@IntDef(flag = false, prefix = "MEDIA_ERROR", value = {
MEDIA_ERROR_UNKNOWN,
MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK,
MEDIA_ERROR_IO,
MEDIA_ERROR_MALFORMED,
MEDIA_ERROR_UNSUPPORTED,
MEDIA_ERROR_TIMED_OUT,
MEDIA_ERROR_SYSTEM
})
@Retention(RetentionPolicy.SOURCE)
public @interface MediaError {}
/* Do not change these values without updating their counterparts
* in include/media/mediaplayer2.h!
@@ -2059,129 +2020,246 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
*/
public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
/**
* @hide
*/
@IntDef(flag = false, prefix = "MEDIA_INFO", value = {
MEDIA_INFO_UNKNOWN,
MEDIA_INFO_STARTED_AS_NEXT,
MEDIA_INFO_VIDEO_RENDERING_START,
MEDIA_INFO_AUDIO_RENDERING_START,
MEDIA_INFO_PLAYBACK_COMPLETE,
MEDIA_INFO_PLAYLIST_END,
MEDIA_INFO_PREPARED,
MEDIA_INFO_VIDEO_TRACK_LAGGING,
MEDIA_INFO_BUFFERING_START,
MEDIA_INFO_BUFFERING_END,
MEDIA_INFO_NETWORK_BANDWIDTH,
MEDIA_INFO_BUFFERING_UPDATE,
MEDIA_INFO_BAD_INTERLEAVING,
MEDIA_INFO_NOT_SEEKABLE,
MEDIA_INFO_METADATA_UPDATE,
MEDIA_INFO_EXTERNAL_METADATA_UPDATE,
MEDIA_INFO_AUDIO_NOT_PLAYING,
MEDIA_INFO_VIDEO_NOT_PLAYING,
MEDIA_INFO_TIMED_TEXT_ERROR,
MEDIA_INFO_UNSUPPORTED_SUBTITLE,
MEDIA_INFO_SUBTITLE_TIMED_OUT
})
@Retention(RetentionPolicy.SOURCE)
public @interface MediaInfo {}
//--------------------------------------------------------------------------
/** The player just completed a call {@link #attachAuxEffect}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_ATTACH_AUX_EFFECT = 1;
public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1;
/** The player just completed a call {@link #deselectTrack}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_DESELECT_TRACK = 2;
public static final int CALL_COMPLETED_DESELECT_TRACK = 2;
/** The player just completed a call {@link #loopCurrent}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_LOOP_CURRENT = 3;
public static final int CALL_COMPLETED_LOOP_CURRENT = 3;
/** The player just completed a call {@link #pause}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_PAUSE = 4;
public static final int CALL_COMPLETED_PAUSE = 4;
/** The player just completed a call {@link #play}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_PLAY = 5;
public static final int CALL_COMPLETED_PLAY = 5;
/** The player just completed a call {@link #prepare}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_PREPARE = 6;
public static final int CALL_COMPLETED_PREPARE = 6;
/** The player just completed a call {@link #releaseDrm}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_RELEASE_DRM = 12;
public static final int CALL_COMPLETED_RELEASE_DRM = 12;
/** The player just completed a call {@link #restoreDrmKeys}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_RESTORE_DRM_KEYS = 13;
public static final int CALL_COMPLETED_RESTORE_DRM_KEYS = 13;
/** The player just completed a call {@link #seekTo}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SEEK_TO = 14;
public static final int CALL_COMPLETED_SEEK_TO = 14;
/** The player just completed a call {@link #selectTrack}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SELECT_TRACK = 15;
public static final int CALL_COMPLETED_SELECT_TRACK = 15;
/** The player just completed a call {@link #setAudioAttributes}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_AUDIO_ATTRIBUTES = 16;
public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16;
/** The player just completed a call {@link #setAudioSessionId}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_AUDIO_SESSION_ID = 17;
public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17;
/** The player just completed a call {@link #setAuxEffectSendLevel}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_AUX_EFFECT_SEND_LEVEL = 18;
public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18;
/** The player just completed a call {@link #setDataSource}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_DATA_SOURCE = 19;
public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19;
/** The player just completed a call {@link #setNextDataSource}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCE = 22;
public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22;
/** The player just completed a call {@link #setNextDataSources}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCES = 23;
public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23;
/** The player just completed a call {@link #setPlaybackParams}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_PLAYBACK_PARAMS = 24;
public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24;
/** The player just completed a call {@link #setPlaybackSpeed}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_PLAYBACK_SPEED = 25;
public static final int CALL_COMPLETED_SET_PLAYBACK_SPEED = 25;
/** The player just completed a call {@link #setPlayerVolume}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_PLAYER_VOLUME = 26;
public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26;
/** The player just completed a call {@link #setSurface}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_SURFACE = 27;
public static final int CALL_COMPLETED_SET_SURFACE = 27;
/** The player just completed a call {@link #setSyncParams}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SET_SYNC_PARAMS = 28;
public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28;
/** The player just completed a call {@link #skipToNext}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int MEDIA_CALL_SKIP_TO_NEXT = 29;
public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29;
/** The player just completed a call {@link #setBufferingParams}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
* @hide
*/
public static final int MEDIA_CALL_SET_BUFFERING_PARAMS = 1001;
public static final int CALL_COMPLETED_SET_BUFFERING_PARAMS = 1001;
/** The player just completed a call {@link #setPreferredDevice}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
/** The player just completed a call {@code setVideoScalingMode}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
* @hide
*/
public static final int MEDIA_CALL_SET_PREFERRED_DEVICE = 1002;
public static final int CALL_COMPLETED_SET_VIDEO_SCALING_MODE = 1002;
/** The player just completed a call {@code notifyWhenCommandLabelReached}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCommandLabelReached
* @hide
*/
public static final int CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED = 1003;
/**
* @hide
*/
@IntDef(flag = false, prefix = "CALL_COMPLETED", value = {
CALL_COMPLETED_ATTACH_AUX_EFFECT,
CALL_COMPLETED_DESELECT_TRACK,
CALL_COMPLETED_LOOP_CURRENT,
CALL_COMPLETED_PAUSE,
CALL_COMPLETED_PLAY,
CALL_COMPLETED_PREPARE,
CALL_COMPLETED_RELEASE_DRM,
CALL_COMPLETED_RESTORE_DRM_KEYS,
CALL_COMPLETED_SEEK_TO,
CALL_COMPLETED_SELECT_TRACK,
CALL_COMPLETED_SET_AUDIO_ATTRIBUTES,
CALL_COMPLETED_SET_AUDIO_SESSION_ID,
CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL,
CALL_COMPLETED_SET_DATA_SOURCE,
CALL_COMPLETED_SET_NEXT_DATA_SOURCE,
CALL_COMPLETED_SET_NEXT_DATA_SOURCES,
CALL_COMPLETED_SET_PLAYBACK_PARAMS,
CALL_COMPLETED_SET_PLAYBACK_SPEED,
CALL_COMPLETED_SET_PLAYER_VOLUME,
CALL_COMPLETED_SET_SURFACE,
CALL_COMPLETED_SET_SYNC_PARAMS,
CALL_COMPLETED_SKIP_TO_NEXT,
CALL_COMPLETED_SET_BUFFERING_PARAMS,
CALL_COMPLETED_SET_VIDEO_SCALING_MODE,
CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED
})
@Retention(RetentionPolicy.SOURCE)
public @interface CallCompleted {}
/** Status code represents that call is completed without an error.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_NO_ERROR = 0;
/** Status code represents that call is ended with an unknown error.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_ERROR_UNKNOWN = Integer.MIN_VALUE;
/** Status code represents that the player is not in valid state for the operation.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_INVALID_OPERATION = 1;
/** Status code represents that the argument is illegal.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_BAD_VALUE = 2;
/** Status code represents that the operation is not allowed.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_PERMISSION_DENIED = 3;
/** Status code represents a file or network related operation error.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_ERROR_IO = 4;
/** Status code represents that DRM operation is called before preparing a DRM scheme through
* {@link #prepareDrm}.
* @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
*/
public static final int CALL_STATUS_NO_DRM_SCHEME = 5;
/**
* @hide
*/
@IntDef(flag = false, prefix = "CALL_STATUS", value = {
CALL_STATUS_NO_ERROR,
CALL_STATUS_ERROR_UNKNOWN,
CALL_STATUS_INVALID_OPERATION,
CALL_STATUS_BAD_VALUE,
CALL_STATUS_PERMISSION_DENIED,
CALL_STATUS_ERROR_IO,
CALL_STATUS_NO_DRM_SCHEME})
@Retention(RetentionPolicy.SOURCE)
public @interface CallStatus {}
// Modular DRM begin
@@ -2238,13 +2316,10 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
*
* @param mp the {@code MediaPlayer2} associated with this callback
* @param dsd the DataSourceDesc of this data source
* @param status the result of DRM preparation which can be
* {@link #PREPARE_DRM_STATUS_SUCCESS},
* {@link #PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR},
* {@link #PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR}, or
* {@link #PREPARE_DRM_STATUS_PREPARATION_ERROR}.
* @param status the result of DRM preparation.
*/
public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd, @PrepareDrmStatusCode int status) { }
public void onDrmPrepared(
MediaPlayer2 mp, DataSourceDesc dsd, @PrepareDrmStatusCode int status) { }
}
/**
@@ -2288,7 +2363,7 @@ public abstract class MediaPlayer2 extends MediaPlayerBase
/** @hide */
@IntDef({
@IntDef(flag = false, prefix = "PREPARE_DRM_STATUS", value = {
PREPARE_DRM_STATUS_SUCCESS,
PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR,
PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,

View File

@@ -213,18 +213,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void play() {
synchronized (mTaskLock) {
mPendingTasks.add(new Task(MEDIA_CALL_PLAY, false) {
@Override
int process() {
stayAwake(true);
_start();
// TODO: define public constants for return value (status).
return 0;
}
});
processPendingTask_l();
}
addTask(new Task(CALL_COMPLETED_PLAY, false) {
@Override
void process() {
stayAwake(true);
_start();
}
});
}
private native void _start() throws IllegalStateException;
@@ -241,17 +236,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void prepare() {
synchronized (mTaskLock) {
mPendingTasks.add(new Task(MEDIA_CALL_PREPARE, true) {
@Override
int process() {
_prepare();
// TODO: define public constants for return value (status).
return 0;
}
});
processPendingTask_l();
}
addTask(new Task(CALL_COMPLETED_PREPARE, true) {
@Override
void process() {
_prepare();
}
});
}
public native void _prepare();
@@ -264,8 +254,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void pause() {
stayAwake(false);
_pause();
addTask(new Task(CALL_COMPLETED_PAUSE, false) {
@Override
void process() {
stayAwake(false);
_pause();
}
});
}
private native void _pause() throws IllegalStateException;
@@ -277,7 +272,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void skipToNext() {
// TODO: switch to next data source and play
addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
@Override
void process() {
// TODO: switch to next data source and play
}
});
}
/**
@@ -357,14 +357,19 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setAudioAttributes(@NonNull AudioAttributes attributes) {
if (attributes == null) {
final String msg = "Cannot set AudioAttributes to null";
throw new IllegalArgumentException(msg);
}
Parcel pattributes = Parcel.obtain();
attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
pattributes.recycle();
addTask(new Task(CALL_COMPLETED_SET_AUDIO_ATTRIBUTES, false) {
@Override
void process() {
if (attributes == null) {
final String msg = "Cannot set AudioAttributes to null";
throw new IllegalArgumentException(msg);
}
Parcel pattributes = Parcel.obtain();
attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
pattributes.recycle();
}
});
}
@Override
@@ -384,16 +389,21 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setDataSource(@NonNull DataSourceDesc dsd) {
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
// TODO: setDataSource could update exist data source
synchronized (mSrcLock) {
mCurrentDSD = dsd;
mCurrentSrcId = mSrcIdGenerator++;
try {
handleDataSource(true /* isCurrent */, dsd, mCurrentSrcId);
} catch (IOException e) {
addTask(new Task(CALL_COMPLETED_SET_DATA_SOURCE, false) {
@Override
void process() {
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
// TODO: setDataSource could update exist data source
synchronized (mSrcLock) {
mCurrentDSD = dsd;
mCurrentSrcId = mSrcIdGenerator++;
try {
handleDataSource(true /* isCurrent */, dsd, mCurrentSrcId);
} catch (IOException e) {
}
}
}
}
});
}
/**
@@ -406,21 +416,25 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setNextDataSource(@NonNull DataSourceDesc dsd) {
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
synchronized (mSrcLock) {
mNextDSDs = new ArrayList<DataSourceDesc>(1);
mNextDSDs.add(dsd);
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
mNextSourcePlayPending = false;
}
int state = getMediaPlayer2State();
if (state != MEDIAPLAYER2_STATE_IDLE) {
synchronized (mSrcLock) {
prepareNextDataSource_l();
addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCE, false) {
@Override
void process() {
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
synchronized (mSrcLock) {
mNextDSDs = new ArrayList<DataSourceDesc>(1);
mNextDSDs.add(dsd);
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
mNextSourcePlayPending = false;
}
int state = getMediaPlayer2State();
if (state != MEDIAPLAYER2_STATE_IDLE) {
synchronized (mSrcLock) {
prepareNextDataSource_l();
}
}
}
}
});
}
/**
@@ -432,28 +446,33 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
if (dsds == null || dsds.size() == 0) {
throw new IllegalArgumentException("data source list cannot be null or empty.");
}
for (DataSourceDesc dsd : dsds) {
if (dsd == null) {
throw new IllegalArgumentException(
"DataSourceDesc in the source list cannot be null.");
}
}
addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCES, false) {
@Override
void process() {
if (dsds == null || dsds.size() == 0) {
throw new IllegalArgumentException("data source list cannot be null or empty.");
}
for (DataSourceDesc dsd : dsds) {
if (dsd == null) {
throw new IllegalArgumentException(
"DataSourceDesc in the source list cannot be null.");
}
}
synchronized (mSrcLock) {
mNextDSDs = new ArrayList(dsds);
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
mNextSourcePlayPending = false;
}
int state = getMediaPlayer2State();
if (state != MEDIAPLAYER2_STATE_IDLE) {
synchronized (mSrcLock) {
prepareNextDataSource_l();
synchronized (mSrcLock) {
mNextDSDs = new ArrayList(dsds);
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
mNextSourcePlayPending = false;
}
int state = getMediaPlayer2State();
if (state != MEDIAPLAYER2_STATE_IDLE) {
synchronized (mSrcLock) {
prepareNextDataSource_l();
}
}
}
}
});
}
@Override
@@ -469,8 +488,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void loopCurrent(boolean loop) {
// TODO: set the looping mode, send notification
setLooping(loop);
addTask(new Task(CALL_COMPLETED_LOOP_CURRENT, false) {
@Override
void process() {
// TODO: set the looping mode, send notification
setLooping(loop);
}
});
}
private native void setLooping(boolean looping);
@@ -486,8 +510,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setPlaybackSpeed(float speed) {
// TODO: send notification
setPlaybackParams(getPlaybackParams().setSpeed(speed));
addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_SPEED, false) {
@Override
void process() {
_setPlaybackParams(getPlaybackParams().setSpeed(speed));
}
});
}
/**
@@ -522,8 +550,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setPlayerVolume(float volume) {
// send notification
_setVolume(volume, volume);
addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
@Override
void process() {
_setVolume(volume, volume);
}
});
}
private native void _setVolume(float leftVolume, float rightVolume);
@@ -630,7 +662,17 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
@Override
public void notifyWhenCommandLabelReached(Object label) {
// TODO: create an entry in command queue
addTask(new Task(CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED, false) {
@Override
void process() {
synchronized (mEventCbLock) {
for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onCommandLabelReached(
MediaPlayer2Impl.this, label));
}
}
}
});
}
/**
@@ -683,12 +725,17 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setSurface(Surface surface) {
if (mScreenOnWhilePlaying && surface != null) {
Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for Surface");
}
mSurfaceHolder = null;
_setVideoSurface(surface);
updateSurfaceScreenOn();
addTask(new Task(CALL_COMPLETED_SET_SURFACE, false) {
@Override
void process() {
if (mScreenOnWhilePlaying && surface != null) {
Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for Surface");
}
mSurfaceHolder = null;
_setVideoSurface(surface);
updateSurfaceScreenOn();
}
});
}
/**
@@ -712,20 +759,25 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setVideoScalingMode(int mode) {
if (!isVideoScalingModeSupported(mode)) {
final String msg = "Scaling mode " + mode + " is not supported";
throw new IllegalArgumentException(msg);
}
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
request.writeInt(mode);
invoke(request, reply);
} finally {
request.recycle();
reply.recycle();
}
addTask(new Task(CALL_COMPLETED_SET_VIDEO_SCALING_MODE, false) {
@Override
void process() {
if (!isVideoScalingModeSupported(mode)) {
final String msg = "Scaling mode " + mode + " is not supported";
throw new IllegalArgumentException(msg);
}
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
request.writeInt(mode);
invoke(request, reply);
} finally {
request.recycle();
reply.recycle();
}
}
});
}
/**
@@ -735,6 +787,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
public void clearPendingCommands() {
}
private void addTask(Task task) {
synchronized (mTaskLock) {
mPendingTasks.add(task);
processPendingTask_l();
}
}
@GuardedBy("mTaskLock")
private void processPendingTask_l() {
if (mCurrentTask != null) {
@@ -1332,7 +1391,17 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* @hide
*/
@Override
public native void setBufferingParams(@NonNull BufferingParams params);
public void setBufferingParams(@NonNull BufferingParams params) {
addTask(new Task(CALL_COMPLETED_SET_BUFFERING_PARAMS, false) {
@Override
void process() {
Preconditions.checkNotNull(params, "the BufferingParams cannot be null");
_setBufferingParams(params);
}
});
}
private native void _setBufferingParams(@NonNull BufferingParams params);
/**
* Sets playback rate and audio mode.
@@ -1386,7 +1455,17 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* @throws IllegalArgumentException if params is not supported.
*/
@Override
public native void setPlaybackParams(@NonNull PlaybackParams params);
public void setPlaybackParams(@NonNull PlaybackParams params) {
addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_PARAMS, false) {
@Override
void process() {
Preconditions.checkNotNull(params, "the PlaybackParams cannot be null");
_setPlaybackParams(params);
}
});
}
private native void _setPlaybackParams(@NonNull PlaybackParams params);
/**
* Gets the playback params, containing the current playback rate.
@@ -1409,7 +1488,17 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* @throws IllegalArgumentException if params are not supported.
*/
@Override
public native void setSyncParams(@NonNull SyncParams params);
public void setSyncParams(@NonNull SyncParams params) {
addTask(new Task(CALL_COMPLETED_SET_SYNC_PARAMS, false) {
@Override
void process() {
Preconditions.checkNotNull(params, "the SyncParams cannot be null");
_setSyncParams(params);
}
});
}
private native void _setSyncParams(@NonNull SyncParams params);
/**
* Gets the A/V sync mode.
@@ -1454,20 +1543,28 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* @throws IllegalArgumentException if the mode is invalid.
*/
@Override
public void seekTo(long msec, @SeekMode int mode) {
if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
final String msg = "Illegal seek mode: " + mode;
throw new IllegalArgumentException(msg);
}
// TODO: pass long to native, instead of truncating here.
if (msec > Integer.MAX_VALUE) {
Log.w(TAG, "seekTo offset " + msec + " is too large, cap to " + Integer.MAX_VALUE);
msec = Integer.MAX_VALUE;
} else if (msec < Integer.MIN_VALUE) {
Log.w(TAG, "seekTo offset " + msec + " is too small, cap to " + Integer.MIN_VALUE);
msec = Integer.MIN_VALUE;
}
_seekTo(msec, mode);
public void seekTo(final long msec, @SeekMode int mode) {
addTask(new Task(CALL_COMPLETED_SEEK_TO, true) {
@Override
void process() {
if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
final String msg = "Illegal seek mode: " + mode;
throw new IllegalArgumentException(msg);
}
// TODO: pass long to native, instead of truncating here.
long posMs = msec;
if (posMs > Integer.MAX_VALUE) {
Log.w(TAG, "seekTo offset " + posMs + " is too large, cap to "
+ Integer.MAX_VALUE);
posMs = Integer.MAX_VALUE;
} else if (posMs < Integer.MIN_VALUE) {
Log.w(TAG, "seekTo offset " + posMs + " is too small, cap to "
+ Integer.MIN_VALUE);
posMs = Integer.MIN_VALUE;
}
_seekTo(posMs, mode);
}
});
}
private native final void _seekTo(long msec, int mode);
@@ -1694,7 +1791,16 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* @throws IllegalArgumentException if the sessionId is invalid.
*/
@Override
public native void setAudioSessionId(int sessionId);
public void setAudioSessionId(int sessionId) {
addTask(new Task(CALL_COMPLETED_SET_AUDIO_SESSION_ID, false) {
@Override
void process() {
_setAudioSessionId(sessionId);
}
});
}
private native void _setAudioSessionId(int sessionId);
/**
* Returns the audio session ID.
@@ -1720,7 +1826,16 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* @param effectId system wide unique id of the effect to attach
*/
@Override
public native void attachAuxEffect(int effectId);
public void attachAuxEffect(int effectId) {
addTask(new Task(CALL_COMPLETED_ATTACH_AUX_EFFECT, false) {
@Override
void process() {
_attachAuxEffect(effectId);
}
});
}
private native void _attachAuxEffect(int effectId);
/**
* Sets the send level of the player to the attached auxiliary effect.
@@ -1736,7 +1851,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void setAuxEffectSendLevel(float level) {
_setAuxEffectSendLevel(level);
addTask(new Task(CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL, false) {
@Override
void process() {
_setAuxEffectSendLevel(level);
}
});
}
private native void _setAuxEffectSendLevel(float level);
@@ -2475,7 +2595,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void selectTrack(int index) {
selectOrDeselectTrack(index, true /* select */);
addTask(new Task(CALL_COMPLETED_SELECT_TRACK, false) {
@Override
void process() {
selectOrDeselectTrack(index, true /* select */);
}
});
}
/**
@@ -2494,7 +2619,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
*/
@Override
public void deselectTrack(int index) {
selectOrDeselectTrack(index, false /* select */);
addTask(new Task(CALL_COMPLETED_DESELECT_TRACK, false) {
@Override
void process() {
selectOrDeselectTrack(index, false /* select */);
}
});
}
private void selectOrDeselectTrack(int index, boolean select)
@@ -2697,8 +2827,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
synchronized (mTaskLock) {
if (mCurrentTask.mMediaCallType == MEDIA_CALL_PREPARE
if (mCurrentTask != null
&& mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
&& mCurrentTask.mDSD == dsd
&& mCurrentTask.mNeedToWaitForEventToComplete) {
mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
mCurrentTask = null;
processPendingTask_l();
}
@@ -2803,10 +2936,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
case MEDIA_SEEK_COMPLETE:
{
synchronized (mEventCbLock) {
for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onCallComplete(
mMediaPlayer, mCurrentDSD, MEDIA_CALL_SEEK_TO, 0));
synchronized (mTaskLock) {
if (mCurrentTask != null
&& mCurrentTask.mMediaCallType == CALL_COMPLETED_SEEK_TO
&& mCurrentTask.mNeedToWaitForEventToComplete) {
mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
mCurrentTask = null;
processPendingTask_l();
}
}
}
@@ -3390,32 +3526,39 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
public void releaseDrm()
throws NoDrmSchemeException
{
Log.v(TAG, "releaseDrm:");
addTask(new Task(CALL_COMPLETED_RELEASE_DRM, false) {
@Override
void process() throws NoDrmSchemeException {
synchronized (mDrmLock) {
Log.v(TAG, "releaseDrm:");
synchronized (mDrmLock) {
if (!mActiveDrmScheme) {
Log.e(TAG, "releaseDrm(): No active DRM scheme to release.");
throw new NoDrmSchemeExceptionImpl("releaseDrm: No active DRM scheme to release.");
if (!mActiveDrmScheme) {
Log.e(TAG, "releaseDrm(): No active DRM scheme to release.");
throw new NoDrmSchemeExceptionImpl(
"releaseDrm: No active DRM scheme to release.");
}
try {
// we don't have the player's state in this layer. The below call raises
// exception if we're in a non-stopped/prepared state.
// for cleaning native/mediaserver crypto object
_releaseDrm();
// for cleaning client-side MediaDrm object; only called if above has succeeded
cleanDrmObj();
mActiveDrmScheme = false;
} catch (IllegalStateException e) {
Log.w(TAG, "releaseDrm: Exception ", e);
throw new IllegalStateException(
"releaseDrm: The player is not in a valid state.");
} catch (Exception e) {
Log.e(TAG, "releaseDrm: Exception ", e);
}
} // synchronized
}
try {
// we don't have the player's state in this layer. The below call raises
// exception if we're in a non-stopped/prepared state.
// for cleaning native/mediaserver crypto object
_releaseDrm();
// for cleaning client-side MediaDrm object; only called if above has succeeded
cleanDrmObj();
mActiveDrmScheme = false;
} catch (IllegalStateException e) {
Log.w(TAG, "releaseDrm: Exception ", e);
throw new IllegalStateException("releaseDrm: The player is not in a valid state.");
} catch (Exception e) {
Log.e(TAG, "releaseDrm: Exception ", e);
}
} // synchronized
});
}
@@ -3470,7 +3613,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
synchronized (mDrmLock) {
if (!mActiveDrmScheme) {
Log.e(TAG, "getDrmKeyRequest NoDrmSchemeException");
throw new NoDrmSchemeExceptionImpl("getDrmKeyRequest: Has to set a DRM scheme first.");
throw new NoDrmSchemeExceptionImpl(
"getDrmKeyRequest: Has to set a DRM scheme first.");
}
try {
@@ -3531,7 +3675,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
if (!mActiveDrmScheme) {
Log.e(TAG, "getDrmKeyRequest NoDrmSchemeException");
throw new NoDrmSchemeExceptionImpl("getDrmKeyRequest: Has to set a DRM scheme first.");
throw new NoDrmSchemeExceptionImpl(
"getDrmKeyRequest: Has to set a DRM scheme first.");
}
try {
@@ -3541,8 +3686,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
byte[] keySetResult = mDrmObj.provideKeyResponse(scope, response);
Log.v(TAG, "provideDrmKeyResponse: keySetId: " + keySetId + " response: " + response +
" --> " + keySetResult);
Log.v(TAG, "provideDrmKeyResponse: keySetId: " + keySetId + " response: " + response
+ " --> " + keySetResult);
return keySetResult;
@@ -3570,23 +3715,29 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
public void restoreDrmKeys(@NonNull byte[] keySetId)
throws NoDrmSchemeException
{
Log.v(TAG, "restoreDrmKeys: keySetId: " + keySetId);
addTask(new Task(CALL_COMPLETED_RESTORE_DRM_KEYS, false) {
@Override
void process() throws NoDrmSchemeException {
Log.v(TAG, "restoreDrmKeys: keySetId: " + keySetId);
synchronized (mDrmLock) {
synchronized (mDrmLock) {
if (!mActiveDrmScheme) {
Log.w(TAG, "restoreDrmKeys NoDrmSchemeException");
throw new NoDrmSchemeExceptionImpl("restoreDrmKeys: Has to set a DRM scheme first.");
if (!mActiveDrmScheme) {
Log.w(TAG, "restoreDrmKeys NoDrmSchemeException");
throw new NoDrmSchemeExceptionImpl(
"restoreDrmKeys: Has to set a DRM scheme first.");
}
try {
mDrmObj.restoreKeys(mDrmSessionId, keySetId);
} catch (Exception e) {
Log.w(TAG, "restoreKeys Exception " + e);
throw e;
}
} // synchronized
}
try {
mDrmObj.restoreKeys(mDrmSessionId, keySetId);
} catch (Exception e) {
Log.w(TAG, "restoreKeys Exception " + e);
throw e;
}
} // synchronized
});
}
@@ -3611,7 +3762,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
if (!mActiveDrmScheme && !mDrmConfigAllowed) {
Log.w(TAG, "getDrmPropertyString NoDrmSchemeException");
throw new NoDrmSchemeExceptionImpl("getDrmPropertyString: Has to prepareDrm() first.");
throw new NoDrmSchemeExceptionImpl(
"getDrmPropertyString: Has to prepareDrm() first.");
}
try {
@@ -3649,7 +3801,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
if ( !mActiveDrmScheme && !mDrmConfigAllowed ) {
Log.w(TAG, "setDrmPropertyString NoDrmSchemeException");
throw new NoDrmSchemeExceptionImpl("setDrmPropertyString: Has to prepareDrm() first.");
throw new NoDrmSchemeExceptionImpl(
"setDrmPropertyString: Has to prepareDrm() first.");
}
try {
@@ -4587,34 +4740,61 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private abstract class Task implements Runnable {
private final int mMediaCallType;
private final boolean mNeedToWaitForEventToComplete;
private DataSourceDesc mDSD;
public Task (int mediaCallType, boolean needToWaitForEventToComplete) {
mMediaCallType = mediaCallType;
mNeedToWaitForEventToComplete = needToWaitForEventToComplete;
}
abstract int process();
abstract void process() throws IOException, NoDrmSchemeException;
@Override
public void run() {
int status = process();
int status = CALL_STATUS_NO_ERROR;
try {
process();
} catch (IllegalStateException e) {
status = CALL_STATUS_INVALID_OPERATION;
} catch (IllegalArgumentException e) {
status = CALL_STATUS_BAD_VALUE;
} catch (SecurityException e) {
status = CALL_STATUS_PERMISSION_DENIED;
} catch (IOException e) {
status = CALL_STATUS_ERROR_IO;
} catch (NoDrmSchemeException e) {
status = CALL_STATUS_NO_DRM_SCHEME;
} catch (Exception e) {
status = CALL_STATUS_ERROR_UNKNOWN;
}
synchronized (mSrcLock) {
mDSD = mCurrentDSD;
}
// TODO: Make native implementations asynchronous and let them send notifications.
if (!mNeedToWaitForEventToComplete || status != CALL_STATUS_NO_ERROR) {
sendCompleteNotification(status);
if (!mNeedToWaitForEventToComplete) {
final DataSourceDesc dsd;
synchronized (mSrcLock) {
dsd = mCurrentDSD;
}
synchronized (mEventCbLock) {
for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onCallComplete(
MediaPlayer2Impl.this, dsd, mMediaCallType, status));
}
}
synchronized (mTaskLock) {
mCurrentTask = null;
processPendingTask_l();
}
}
}
private void sendCompleteNotification(int status) {
// In {@link #notifyWhenCommandLabelReached} case, a separate callback
// {#link #onCommandLabelReached} is already called in {@code process()}.
if (mMediaCallType == CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED) {
return;
}
synchronized (mEventCbLock) {
for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onCallCompleted(
MediaPlayer2Impl.this, mDSD, mMediaCallType, status));
}
}
}
};
}

View File

@@ -1489,7 +1489,7 @@ static const JNINativeMethod gMethods[] = {
{"nativePlayNextDataSource", "(J)V", (void *)android_media_MediaPlayer2_playNextDataSource},
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer2_setVideoSurface},
{"getBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer2_getBufferingParams},
{"setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer2_setBufferingParams},
{"_setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer2_setBufferingParams},
{"_prepare", "()V", (void *)android_media_MediaPlayer2_prepare},
{"_start", "()V", (void *)android_media_MediaPlayer2_start},
{"_stop", "()V", (void *)android_media_MediaPlayer2_stop},
@@ -1497,9 +1497,9 @@ static const JNINativeMethod gMethods[] = {
{"getVideoWidth", "()I", (void *)android_media_MediaPlayer2_getVideoWidth},
{"getVideoHeight", "()I", (void *)android_media_MediaPlayer2_getVideoHeight},
{"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_MediaPlayer2_native_getMetrics},
{"setPlaybackParams", "(Landroid/media/PlaybackParams;)V", (void *)android_media_MediaPlayer2_setPlaybackParams},
{"_setPlaybackParams", "(Landroid/media/PlaybackParams;)V", (void *)android_media_MediaPlayer2_setPlaybackParams},
{"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer2_getPlaybackParams},
{"setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer2_setSyncParams},
{"_setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer2_setSyncParams},
{"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer2_getSyncParams},
{"_seekTo", "(JI)V", (void *)android_media_MediaPlayer2_seekTo},
{"_notifyAt", "(J)V", (void *)android_media_MediaPlayer2_notifyAt},
@@ -1522,9 +1522,9 @@ static const JNINativeMethod gMethods[] = {
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer2_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer2_native_finalize},
{"getAudioSessionId", "()I", (void *)android_media_MediaPlayer2_get_audio_session_id},
{"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer2_set_audio_session_id},
{"_setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer2_set_audio_session_id},
{"_setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer2_setAuxEffectSendLevel},
{"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer2_attachAuxEffect},
{"_attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer2_attachAuxEffect},
// Modular DRM
{ "_prepareDrm", "([B[B)V", (void *)android_media_MediaPlayer2_prepareDrm },
{ "_releaseDrm", "()V", (void *)android_media_MediaPlayer2_releaseDrm },