diff --git a/api/current.txt b/api/current.txt index 7672fb0e60f40..c8c3cfe466c67 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24351,7 +24351,6 @@ package android.media { method public abstract android.media.MediaDrm.KeyRequest getDrmKeyRequest(byte[], byte[], java.lang.String, int, java.util.Map) 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); diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java index 08defbbe66976..ece19b9ca37b3 100644 --- a/media/java/android/media/MediaPlayer2.java +++ b/media/java/android/media/MediaPlayer2.java @@ -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)}. *
  • 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: - * + * @param what the type of error that has occurred. * @param extra an extra code, specific to the error. Typically * implementation dependent. - * */ - 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. - * * @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. - * * @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, diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java index ee1bb50e57058..1c4d898acb4f0 100644 --- a/media/java/android/media/MediaPlayer2Impl.java +++ b/media/java/android/media/MediaPlayer2Impl.java @@ -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(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(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 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 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 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 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 cb : mEventCallbackRecords) { + cb.first.execute(() -> cb.second.onCallCompleted( + MediaPlayer2Impl.this, mDSD, mMediaCallType, status)); + } + } + } }; } diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp index 918b82b065703..918a375a6e832 100644 --- a/media/jni/android_media_MediaPlayer2.cpp +++ b/media/jni/android_media_MediaPlayer2.cpp @@ -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 },