Loading media/java/android/media/MediaPlayer2.java +2 −11 Original line number Diff line number Diff line Loading @@ -96,22 +96,13 @@ import java.util.UUID; * {@link #close()} is called, it is in the <em>End</em> state. Between these * two states is the life cycle of the MediaPlayer2 object. * <ul> * <li>There is a subtle but important difference between a newly constructed * MediaPlayer2 object and the MediaPlayer2 object after {@link #reset()} * is called. It is a programming error to invoke methods such * <li> It is a programming error to invoke methods such * as {@link #getCurrentPosition()}, * {@link #getDuration()}, {@link #getVideoHeight()}, * {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)}, * {@link #setVolume(float, float)}, {@link #pause()}, {@link #play()}, * {@link #seekTo(long, int)} or * {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these * methods is called right after a MediaPlayer2 object is constructed, * the user supplied callback method OnErrorListener.onError() won't be * called by the internal player engine and the object state remains * unchanged; but if these methods are called right after {@link #reset()}, * the user supplied callback method OnErrorListener.onError() will be * invoked by the internal player engine and the object will be * transfered to the <em>Error</em> state. </li> * {@link #prepareAsync()} in the <em>Idle</em> state. * <li>It is also recommended that once * a MediaPlayer2 object is no longer being used, call {@link #close()} immediately * so that resources used by the internal player engine associated with the Loading media/java/android/media/MediaPlayer2Impl.java +148 −135 Original line number Diff line number Diff line Loading @@ -1960,6 +1960,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { mTimeProvider = null; } synchronized (mEventCbLock) { mEventCallbackRecords.clear(); } synchronized (mDrmEventCbLock) { mDrmEventCallbackRecords.clear(); } stayAwake(false); _reset(); // make sure none of the listeners get called anymore Loading Loading @@ -3049,8 +3056,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { stayAwake(false); updateSurfaceScreenOn(); synchronized (mEventCbLock) { mEventCb = null; mEventExec = null; mEventCallbackRecords.clear(); } if (mTimeProvider != null) { mTimeProvider.close(); Loading @@ -3061,8 +3067,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // Modular DRM clean up mOnDrmConfigHelper = null; synchronized (mDrmEventCbLock) { mDrmEventCb = null; mDrmEventExec = null; mDrmEventCallbackRecords.clear(); } resetDrmState(); Loading Loading @@ -3118,18 +3123,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { Log.w(TAG, "mediaplayer2 went away with unhandled events"); return; } final Executor eventExec; final EventCallback eventCb; synchronized (mEventCbLock) { eventExec = mEventExec; eventCb = mEventCb; } final Executor drmEventExec; final DrmEventCallback drmEventCb; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; } final int what = msg.arg1; final int extra = msg.arg2; switch(msg.what) { case MEDIA_PREPARED: try { Loading @@ -3143,19 +3138,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { sendMessage(msg2); } if (eventCb != null && eventExec != null) { eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_PREPARED, 0)); } } return; case MEDIA_DRM_INFO: Log.v(TAG, "MEDIA_DRM_INFO " + mDrmEventCb); if (msg.obj == null) { Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL"); } else if (msg.obj instanceof Parcel) { if (drmEventExec != null && drmEventCb != null) { // The parcel was parsed already in postEventFromNative final DrmInfoImpl drmInfo; Loading @@ -3169,7 +3163,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // notifying the client outside the lock if (drmInfo != null) { drmEventExec.execute(() -> drmEventCb.onDrmInfo(mMediaPlayer, drmInfo)); synchronized (mEventCbLock) { for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { cb.first.execute(() -> cb.second.onDrmInfo( mMediaPlayer, drmInfo)); } } } } else { Loading @@ -3178,10 +3176,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_PLAYBACK_COMPLETE: if (eventCb != null && eventExec != null) { eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_PLAYBACK_COMPLETE, 0)); } } stayAwake(false); return; Loading @@ -3205,17 +3205,22 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { break; case MEDIA_BUFFERING_UPDATE: if (eventCb != null && eventExec != null) { final int percent = msg.arg1; eventExec.execute(() -> eventCb.onBufferingUpdate(mMediaPlayer, 0, percent)); synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onBufferingUpdate( mMediaPlayer, 0, percent)); } } return; case MEDIA_SEEK_COMPLETE: if (eventCb != null && eventExec != null) { eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_COMPLETE_CALL_SEEK, 0)); } } // fall through case MEDIA_SKIPPED: Loading @@ -3228,23 +3233,26 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_SET_VIDEO_SIZE: if (eventCb != null && eventExec != null) { final int width = msg.arg1; final int height = msg.arg2; eventExec.execute(() -> eventCb.onVideoSizeChanged( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onVideoSizeChanged( mMediaPlayer, 0, width, height)); } } return; case MEDIA_ERROR: Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")"); if (eventCb != null && eventExec != null) { final int what = msg.arg1; final int extra = msg.arg2; eventExec.execute(() -> eventCb.onError(mMediaPlayer, 0, what, extra)); eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onError( mMediaPlayer, 0, what, extra)); cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_PLAYBACK_COMPLETE, 0)); } } stayAwake(false); return; Loading @@ -3253,12 +3261,14 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { case MEDIA_INFO_VIDEO_TRACK_LAGGING: Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")"); break; case MEDIA_INFO_METADATA_UPDATE: try { scanInternalSubtitleTracks(); } catch (RuntimeException e) { Message msg2 = obtainMessage( MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null); MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null); sendMessage(msg2); } // fall through Loading @@ -3270,6 +3280,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { mSubtitleController.selectDefaultTrack(); } break; case MEDIA_INFO_BUFFERING_START: case MEDIA_INFO_BUFFERING_END: TimeProvider timeProvider = mTimeProvider; Loading @@ -3279,10 +3290,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { break; } if (eventCb != null && eventExec != null) { final int what = msg.arg1; final int extra = msg.arg2; eventExec.execute(() -> eventCb.onInfo(mMediaPlayer, 0, what, extra)); synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, what, extra)); } } // No real default action so far. return; Loading @@ -3295,17 +3307,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_TIMED_TEXT: if (eventCb == null || eventExec == null) { return; } if (msg.obj == null) { eventExec.execute(() -> eventCb.onTimedText(mMediaPlayer, 0, null)); } else { final TimedText text; if (msg.obj instanceof Parcel) { Parcel parcel = (Parcel)msg.obj; TimedText text = new TimedText(parcel); text = new TimedText(parcel); parcel.recycle(); eventExec.execute(() -> eventCb.onTimedText(mMediaPlayer, 0, text)); } else { text = null; } synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onTimedText(mMediaPlayer, 0, text)); } } return; Loading @@ -3324,16 +3337,21 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_META_DATA: if (eventCb == null || eventExec == null) { return; } final TimedMetaData data; if (msg.obj instanceof Parcel) { Parcel parcel = (Parcel) msg.obj; TimedMetaData data = TimedMetaData.createTimedMetaDataFromParcel(parcel); data = TimedMetaData.createTimedMetaDataFromParcel(parcel); parcel.recycle(); eventExec.execute(() -> eventCb.onTimedMetaDataAvailable( } else { data = null; } synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onTimedMetaDataAvailable( mMediaPlayer, 0, data)); } } return; case MEDIA_NOP: // interface test message - ignore Loading Loading @@ -3420,9 +3438,9 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } } private Executor mEventExec; private EventCallback mEventCb; private final Object mEventCbLock = new Object(); private ArrayList<Pair<Executor, EventCallback> > mEventCallbackRecords = new ArrayList<Pair<Executor, EventCallback> >(); /** * Register a callback to be invoked when the media source is ready Loading @@ -3441,9 +3459,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { throw new IllegalArgumentException("Illegal null Executor for the EventCallback"); } synchronized (mEventCbLock) { // TODO: support multiple callbacks. mEventExec = executor; mEventCb = eventCallback; mEventCallbackRecords.add(new Pair(executor, eventCallback)); } } Loading @@ -3455,9 +3471,10 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public void unregisterEventCallback(EventCallback callback) { synchronized (mEventCbLock) { if (callback == mEventCb) { mEventExec = null; mEventCb = null; for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { if (cb.second == callback) { mEventCallbackRecords.remove(cb); } } } } Loading Loading @@ -3497,9 +3514,9 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { private OnDrmConfigHelper mOnDrmConfigHelper; private Executor mDrmEventExec; private DrmEventCallback mDrmEventCb; private final Object mDrmEventCbLock = new Object(); private ArrayList<Pair<Executor, DrmEventCallback> > mDrmEventCallbackRecords = new ArrayList<Pair<Executor, DrmEventCallback> >(); /** * Register a callback to be invoked when the media source is ready Loading @@ -3518,9 +3535,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { throw new IllegalArgumentException("Illegal null Executor for the EventCallback"); } synchronized (mDrmEventCbLock) { // TODO: support multiple callbacks. mDrmEventExec = executor; mDrmEventCb = eventCallback; mDrmEventCallbackRecords.add(new Pair(executor, eventCallback)); } } Loading @@ -3532,9 +3547,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public void unregisterDrmEventCallback(DrmEventCallback callback) { synchronized (mDrmEventCbLock) { if (callback == mDrmEventCb) { mDrmEventExec = null; mDrmEventCb = null; for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { if (cb.second == callback) { mDrmEventCallbackRecords.remove(cb); break; } } } } Loading Loading @@ -3733,17 +3750,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // if finished successfully without provisioning, call the callback outside the lock if (allDoneWithoutProvisioning) { final Executor drmEventExec; final DrmEventCallback drmEventCb; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; } if (drmEventExec != null && drmEventCb != null) { drmEventExec.execute(() -> drmEventCb.onDrmPrepared( for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { cb.first.execute(() -> cb.second.onDrmPrepared( this, PREPARE_DRM_STATUS_SUCCESS)); } } } } Loading Loading @@ -4324,14 +4337,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { boolean succeeded = false; final Executor drmEventExec; final DrmEventCallback drmEventCb; boolean hasCallback = false; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; hasCallback = !mDrmEventCallbackRecords.isEmpty(); } // non-blocking mode needs the lock if (drmEventExec != null && drmEventCb != null) { if (hasCallback) { synchronized (drmLock) { // continuing with prepareDrm Loading @@ -4349,7 +4360,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } // synchronized // calling the callback outside the lock drmEventExec.execute(() -> drmEventCb.onDrmPrepared(mediaPlayer, status)); synchronized (mDrmEventCbLock) { for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { cb.first.execute(() -> cb.second.onDrmPrepared(mediaPlayer, status)); } } } else { // blocking mode already has the lock // continuing with prepareDrm Loading Loading @@ -4397,13 +4412,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { int result; // non-blocking: this is not the final result final Executor drmEventExec; final DrmEventCallback drmEventCb; boolean hasCallback = false; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; hasCallback = !mDrmEventCallbackRecords.isEmpty(); } if (drmEventCb != null && drmEventExec != null) { if (hasCallback) { result = PREPARE_DRM_STATUS_SUCCESS; } else { // if blocking mode, wait till provisioning is done Loading Loading
media/java/android/media/MediaPlayer2.java +2 −11 Original line number Diff line number Diff line Loading @@ -96,22 +96,13 @@ import java.util.UUID; * {@link #close()} is called, it is in the <em>End</em> state. Between these * two states is the life cycle of the MediaPlayer2 object. * <ul> * <li>There is a subtle but important difference between a newly constructed * MediaPlayer2 object and the MediaPlayer2 object after {@link #reset()} * is called. It is a programming error to invoke methods such * <li> It is a programming error to invoke methods such * as {@link #getCurrentPosition()}, * {@link #getDuration()}, {@link #getVideoHeight()}, * {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)}, * {@link #setVolume(float, float)}, {@link #pause()}, {@link #play()}, * {@link #seekTo(long, int)} or * {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these * methods is called right after a MediaPlayer2 object is constructed, * the user supplied callback method OnErrorListener.onError() won't be * called by the internal player engine and the object state remains * unchanged; but if these methods are called right after {@link #reset()}, * the user supplied callback method OnErrorListener.onError() will be * invoked by the internal player engine and the object will be * transfered to the <em>Error</em> state. </li> * {@link #prepareAsync()} in the <em>Idle</em> state. * <li>It is also recommended that once * a MediaPlayer2 object is no longer being used, call {@link #close()} immediately * so that resources used by the internal player engine associated with the Loading
media/java/android/media/MediaPlayer2Impl.java +148 −135 Original line number Diff line number Diff line Loading @@ -1960,6 +1960,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { mTimeProvider = null; } synchronized (mEventCbLock) { mEventCallbackRecords.clear(); } synchronized (mDrmEventCbLock) { mDrmEventCallbackRecords.clear(); } stayAwake(false); _reset(); // make sure none of the listeners get called anymore Loading Loading @@ -3049,8 +3056,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { stayAwake(false); updateSurfaceScreenOn(); synchronized (mEventCbLock) { mEventCb = null; mEventExec = null; mEventCallbackRecords.clear(); } if (mTimeProvider != null) { mTimeProvider.close(); Loading @@ -3061,8 +3067,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // Modular DRM clean up mOnDrmConfigHelper = null; synchronized (mDrmEventCbLock) { mDrmEventCb = null; mDrmEventExec = null; mDrmEventCallbackRecords.clear(); } resetDrmState(); Loading Loading @@ -3118,18 +3123,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { Log.w(TAG, "mediaplayer2 went away with unhandled events"); return; } final Executor eventExec; final EventCallback eventCb; synchronized (mEventCbLock) { eventExec = mEventExec; eventCb = mEventCb; } final Executor drmEventExec; final DrmEventCallback drmEventCb; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; } final int what = msg.arg1; final int extra = msg.arg2; switch(msg.what) { case MEDIA_PREPARED: try { Loading @@ -3143,19 +3138,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { sendMessage(msg2); } if (eventCb != null && eventExec != null) { eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_PREPARED, 0)); } } return; case MEDIA_DRM_INFO: Log.v(TAG, "MEDIA_DRM_INFO " + mDrmEventCb); if (msg.obj == null) { Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL"); } else if (msg.obj instanceof Parcel) { if (drmEventExec != null && drmEventCb != null) { // The parcel was parsed already in postEventFromNative final DrmInfoImpl drmInfo; Loading @@ -3169,7 +3163,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // notifying the client outside the lock if (drmInfo != null) { drmEventExec.execute(() -> drmEventCb.onDrmInfo(mMediaPlayer, drmInfo)); synchronized (mEventCbLock) { for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { cb.first.execute(() -> cb.second.onDrmInfo( mMediaPlayer, drmInfo)); } } } } else { Loading @@ -3178,10 +3176,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_PLAYBACK_COMPLETE: if (eventCb != null && eventExec != null) { eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_PLAYBACK_COMPLETE, 0)); } } stayAwake(false); return; Loading @@ -3205,17 +3205,22 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { break; case MEDIA_BUFFERING_UPDATE: if (eventCb != null && eventExec != null) { final int percent = msg.arg1; eventExec.execute(() -> eventCb.onBufferingUpdate(mMediaPlayer, 0, percent)); synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onBufferingUpdate( mMediaPlayer, 0, percent)); } } return; case MEDIA_SEEK_COMPLETE: if (eventCb != null && eventExec != null) { eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_COMPLETE_CALL_SEEK, 0)); } } // fall through case MEDIA_SKIPPED: Loading @@ -3228,23 +3233,26 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_SET_VIDEO_SIZE: if (eventCb != null && eventExec != null) { final int width = msg.arg1; final int height = msg.arg2; eventExec.execute(() -> eventCb.onVideoSizeChanged( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onVideoSizeChanged( mMediaPlayer, 0, width, height)); } } return; case MEDIA_ERROR: Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")"); if (eventCb != null && eventExec != null) { final int what = msg.arg1; final int extra = msg.arg2; eventExec.execute(() -> eventCb.onError(mMediaPlayer, 0, what, extra)); eventExec.execute(() -> eventCb.onInfo( synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onError( mMediaPlayer, 0, what, extra)); cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, MEDIA_INFO_PLAYBACK_COMPLETE, 0)); } } stayAwake(false); return; Loading @@ -3253,12 +3261,14 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { case MEDIA_INFO_VIDEO_TRACK_LAGGING: Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")"); break; case MEDIA_INFO_METADATA_UPDATE: try { scanInternalSubtitleTracks(); } catch (RuntimeException e) { Message msg2 = obtainMessage( MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null); MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null); sendMessage(msg2); } // fall through Loading @@ -3270,6 +3280,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { mSubtitleController.selectDefaultTrack(); } break; case MEDIA_INFO_BUFFERING_START: case MEDIA_INFO_BUFFERING_END: TimeProvider timeProvider = mTimeProvider; Loading @@ -3279,10 +3290,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { break; } if (eventCb != null && eventExec != null) { final int what = msg.arg1; final int extra = msg.arg2; eventExec.execute(() -> eventCb.onInfo(mMediaPlayer, 0, what, extra)); synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onInfo( mMediaPlayer, 0, what, extra)); } } // No real default action so far. return; Loading @@ -3295,17 +3307,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_TIMED_TEXT: if (eventCb == null || eventExec == null) { return; } if (msg.obj == null) { eventExec.execute(() -> eventCb.onTimedText(mMediaPlayer, 0, null)); } else { final TimedText text; if (msg.obj instanceof Parcel) { Parcel parcel = (Parcel)msg.obj; TimedText text = new TimedText(parcel); text = new TimedText(parcel); parcel.recycle(); eventExec.execute(() -> eventCb.onTimedText(mMediaPlayer, 0, text)); } else { text = null; } synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onTimedText(mMediaPlayer, 0, text)); } } return; Loading @@ -3324,16 +3337,21 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return; case MEDIA_META_DATA: if (eventCb == null || eventExec == null) { return; } final TimedMetaData data; if (msg.obj instanceof Parcel) { Parcel parcel = (Parcel) msg.obj; TimedMetaData data = TimedMetaData.createTimedMetaDataFromParcel(parcel); data = TimedMetaData.createTimedMetaDataFromParcel(parcel); parcel.recycle(); eventExec.execute(() -> eventCb.onTimedMetaDataAvailable( } else { data = null; } synchronized (mEventCbLock) { for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onTimedMetaDataAvailable( mMediaPlayer, 0, data)); } } return; case MEDIA_NOP: // interface test message - ignore Loading Loading @@ -3420,9 +3438,9 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } } private Executor mEventExec; private EventCallback mEventCb; private final Object mEventCbLock = new Object(); private ArrayList<Pair<Executor, EventCallback> > mEventCallbackRecords = new ArrayList<Pair<Executor, EventCallback> >(); /** * Register a callback to be invoked when the media source is ready Loading @@ -3441,9 +3459,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { throw new IllegalArgumentException("Illegal null Executor for the EventCallback"); } synchronized (mEventCbLock) { // TODO: support multiple callbacks. mEventExec = executor; mEventCb = eventCallback; mEventCallbackRecords.add(new Pair(executor, eventCallback)); } } Loading @@ -3455,9 +3471,10 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public void unregisterEventCallback(EventCallback callback) { synchronized (mEventCbLock) { if (callback == mEventCb) { mEventExec = null; mEventCb = null; for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { if (cb.second == callback) { mEventCallbackRecords.remove(cb); } } } } Loading Loading @@ -3497,9 +3514,9 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { private OnDrmConfigHelper mOnDrmConfigHelper; private Executor mDrmEventExec; private DrmEventCallback mDrmEventCb; private final Object mDrmEventCbLock = new Object(); private ArrayList<Pair<Executor, DrmEventCallback> > mDrmEventCallbackRecords = new ArrayList<Pair<Executor, DrmEventCallback> >(); /** * Register a callback to be invoked when the media source is ready Loading @@ -3518,9 +3535,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { throw new IllegalArgumentException("Illegal null Executor for the EventCallback"); } synchronized (mDrmEventCbLock) { // TODO: support multiple callbacks. mDrmEventExec = executor; mDrmEventCb = eventCallback; mDrmEventCallbackRecords.add(new Pair(executor, eventCallback)); } } Loading @@ -3532,9 +3547,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public void unregisterDrmEventCallback(DrmEventCallback callback) { synchronized (mDrmEventCbLock) { if (callback == mDrmEventCb) { mDrmEventExec = null; mDrmEventCb = null; for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { if (cb.second == callback) { mDrmEventCallbackRecords.remove(cb); break; } } } } Loading Loading @@ -3733,17 +3750,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // if finished successfully without provisioning, call the callback outside the lock if (allDoneWithoutProvisioning) { final Executor drmEventExec; final DrmEventCallback drmEventCb; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; } if (drmEventExec != null && drmEventCb != null) { drmEventExec.execute(() -> drmEventCb.onDrmPrepared( for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { cb.first.execute(() -> cb.second.onDrmPrepared( this, PREPARE_DRM_STATUS_SUCCESS)); } } } } Loading Loading @@ -4324,14 +4337,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { boolean succeeded = false; final Executor drmEventExec; final DrmEventCallback drmEventCb; boolean hasCallback = false; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; hasCallback = !mDrmEventCallbackRecords.isEmpty(); } // non-blocking mode needs the lock if (drmEventExec != null && drmEventCb != null) { if (hasCallback) { synchronized (drmLock) { // continuing with prepareDrm Loading @@ -4349,7 +4360,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } // synchronized // calling the callback outside the lock drmEventExec.execute(() -> drmEventCb.onDrmPrepared(mediaPlayer, status)); synchronized (mDrmEventCbLock) { for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) { cb.first.execute(() -> cb.second.onDrmPrepared(mediaPlayer, status)); } } } else { // blocking mode already has the lock // continuing with prepareDrm Loading Loading @@ -4397,13 +4412,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { int result; // non-blocking: this is not the final result final Executor drmEventExec; final DrmEventCallback drmEventCb; boolean hasCallback = false; synchronized (mDrmEventCbLock) { drmEventExec = mDrmEventExec; drmEventCb = mDrmEventCb; hasCallback = !mDrmEventCallbackRecords.isEmpty(); } if (drmEventCb != null && drmEventExec != null) { if (hasCallback) { result = PREPARE_DRM_STATUS_SUCCESS; } else { // if blocking mode, wait till provisioning is done Loading