public void handleMessage()

in android/media/MediaPlayer2Impl.java [2780:3125]


        public void handleMessage(Message msg, long srcId) {
            if (mMediaPlayer.mNativeContext == 0) {
                Log.w(TAG, "mediaplayer2 went away with unhandled events");
                return;
            }
            final int what = msg.arg1;
            final int extra = msg.arg2;

            switch(msg.what) {
            case MEDIA_PREPARED:
            {
                try {
                    scanInternalSubtitleTracks();
                } catch (RuntimeException e) {
                    // send error message instead of crashing;
                    // send error message instead of inlining a call to onError
                    // to avoid code duplication.
                    Message msg2 = obtainMessage(
                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
                    sendMessage(msg2);
                }

                final DataSourceDesc dsd;
                synchronized (mSrcLock) {
                    Log.i(TAG, "MEDIA_PREPARED: srcId=" + srcId
                            + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
                    if (srcId == mCurrentSrcId) {
                        dsd = mCurrentDSD;
                        prepareNextDataSource_l();
                    } else if (mNextDSDs != null && !mNextDSDs.isEmpty()
                            && srcId == mNextSrcId) {
                        dsd = mNextDSDs.get(0);
                        mNextSourceState = NEXT_SOURCE_STATE_PREPARED;
                        if (mNextSourcePlayPending) {
                            playNextDataSource_l();
                        }
                    } else {
                        dsd = null;
                    }
                }

                if (dsd != null) {
                    synchronized (mEventCbLock) {
                        for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                            cb.first.execute(() -> cb.second.onInfo(
                                    mMediaPlayer, dsd, MEDIA_INFO_PREPARED, 0));
                        }
                    }
                }
                synchronized (mTaskLock) {
                    if (mCurrentTask != null
                            && mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
                            && mCurrentTask.mDSD == dsd
                            && mCurrentTask.mNeedToWaitForEventToComplete) {
                        mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
                        mCurrentTask = null;
                        processPendingTask_l();
                    }
                }
                return;
            }

            case MEDIA_DRM_INFO:
            {
                if (msg.obj == null) {
                    Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL");
                } else if (msg.obj instanceof Parcel) {
                    // The parcel was parsed already in postEventFromNative
                    final DrmInfoImpl drmInfo;

                    synchronized (mDrmLock) {
                        if (mDrmInfoImpl != null) {
                            drmInfo = mDrmInfoImpl.makeCopy();
                        } else {
                            drmInfo = null;
                        }
                    }

                    // notifying the client outside the lock
                    if (drmInfo != null) {
                        synchronized (mEventCbLock) {
                            for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
                                cb.first.execute(() -> cb.second.onDrmInfo(
                                        mMediaPlayer, mCurrentDSD, drmInfo));
                            }
                        }
                    }
                } else {
                    Log.w(TAG, "MEDIA_DRM_INFO msg.obj of unexpected type " + msg.obj);
                }
                return;
            }

            case MEDIA_PLAYBACK_COMPLETE:
            {
                final DataSourceDesc dsd = mCurrentDSD;
                synchronized (mSrcLock) {
                    if (srcId == mCurrentSrcId) {
                        Log.i(TAG, "MEDIA_PLAYBACK_COMPLETE: srcId=" + srcId
                                + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
                        playNextDataSource_l();
                    }
                }

                synchronized (mEventCbLock) {
                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onInfo(
                                mMediaPlayer, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
                    }
                }
                stayAwake(false);
                return;
            }

            case MEDIA_STOPPED:
            {
                TimeProvider timeProvider = mTimeProvider;
                if (timeProvider != null) {
                    timeProvider.onStopped();
                }
                break;
            }

            case MEDIA_STARTED:
            case MEDIA_PAUSED:
            {
                TimeProvider timeProvider = mTimeProvider;
                if (timeProvider != null) {
                    timeProvider.onPaused(msg.what == MEDIA_PAUSED);
                }
                break;
            }

            case MEDIA_BUFFERING_UPDATE:
            {
                final int percent = msg.arg1;
                synchronized (mEventCbLock) {
                    if (srcId == mCurrentSrcId) {
                        mBufferedPercentageCurrent.set(percent);
                        for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                            cb.first.execute(() -> cb.second.onInfo(
                                    mMediaPlayer, mCurrentDSD, MEDIA_INFO_BUFFERING_UPDATE,
                                    percent));
                        }
                    } else if (srcId == mNextSrcId && !mNextDSDs.isEmpty()) {
                        mBufferedPercentageNext.set(percent);
                        DataSourceDesc nextDSD = mNextDSDs.get(0);
                        for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                            cb.first.execute(() -> cb.second.onInfo(
                                    mMediaPlayer, nextDSD, MEDIA_INFO_BUFFERING_UPDATE,
                                    percent));
                        }
                    }
                }
                return;
            }

            case MEDIA_SEEK_COMPLETE:
            {
                synchronized (mTaskLock) {
                    if (mCurrentTask != null
                            && mCurrentTask.mMediaCallType == CALL_COMPLETED_SEEK_TO
                            && mCurrentTask.mNeedToWaitForEventToComplete) {
                        mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
                        mCurrentTask = null;
                        processPendingTask_l();
                    }
                }
            }
                // fall through

            case MEDIA_SKIPPED:
            {
                TimeProvider timeProvider = mTimeProvider;
                if (timeProvider != null) {
                    timeProvider.onSeekComplete(mMediaPlayer);
                }
                return;
            }

            case MEDIA_SET_VIDEO_SIZE:
            {
                final int width = msg.arg1;
                final int height = msg.arg2;
                synchronized (mEventCbLock) {
                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onVideoSizeChanged(
                                mMediaPlayer, mCurrentDSD, width, height));
                    }
                }
                return;
            }

            case MEDIA_ERROR:
            {
                Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
                synchronized (mEventCbLock) {
                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onError(
                                mMediaPlayer, mCurrentDSD, what, extra));
                        cb.first.execute(() -> cb.second.onInfo(
                                mMediaPlayer, mCurrentDSD, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
                    }
                }
                stayAwake(false);
                return;
            }

            case MEDIA_INFO:
            {
                switch (msg.arg1) {
                    case MEDIA_INFO_STARTED_AS_NEXT:
                        if (srcId == mCurrentSrcId) {
                            prepareNextDataSource_l();
                        }
                        break;

                    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);
                            sendMessage(msg2);
                        }
                        // fall through

                    case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
                        msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
                        // update default track selection
                        if (mSubtitleController != null) {
                            mSubtitleController.selectDefaultTrack();
                        }
                        break;

                    case MEDIA_INFO_BUFFERING_START:
                    case MEDIA_INFO_BUFFERING_END:
                        TimeProvider timeProvider = mTimeProvider;
                        if (timeProvider != null) {
                            timeProvider.onBuffering(msg.arg1 == MEDIA_INFO_BUFFERING_START);
                        }
                        break;
                }

                synchronized (mEventCbLock) {
                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onInfo(
                                mMediaPlayer, mCurrentDSD, what, extra));
                    }
                }
                // No real default action so far.
                return;
            }

            case MEDIA_NOTIFY_TIME:
            {
                TimeProvider timeProvider = mTimeProvider;
                if (timeProvider != null) {
                    timeProvider.onNotifyTime();
                }
                return;
            }

            case MEDIA_TIMED_TEXT:
            {
                final TimedText text;
                if (msg.obj instanceof Parcel) {
                    Parcel parcel = (Parcel)msg.obj;
                    text = new TimedText(parcel);
                    parcel.recycle();
                } else {
                    text = null;
                }

                synchronized (mEventCbLock) {
                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onTimedText(mMediaPlayer, mCurrentDSD, text));
                    }
                }
                return;
            }

            case MEDIA_SUBTITLE_DATA:
            {
                OnSubtitleDataListener onSubtitleDataListener = mOnSubtitleDataListener;
                if (onSubtitleDataListener == null) {
                    return;
                }
                if (msg.obj instanceof Parcel) {
                    Parcel parcel = (Parcel) msg.obj;
                    SubtitleData data = new SubtitleData(parcel);
                    parcel.recycle();
                    onSubtitleDataListener.onSubtitleData(mMediaPlayer, data);
                }
                return;
            }

            case MEDIA_META_DATA:
            {
                final TimedMetaData data;
                if (msg.obj instanceof Parcel) {
                    Parcel parcel = (Parcel) msg.obj;
                    data = TimedMetaData.createTimedMetaDataFromParcel(parcel);
                    parcel.recycle();
                } else {
                    data = null;
                }

                synchronized (mEventCbLock) {
                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onTimedMetaDataAvailable(
                                mMediaPlayer, mCurrentDSD, data));
                    }
                }
                return;
            }

            case MEDIA_NOP: // interface test message - ignore
            {
                break;
            }

            case MEDIA_AUDIO_ROUTING_CHANGED:
            {
                AudioManager.resetAudioPortGeneration();
                synchronized (mRoutingChangeListeners) {
                    for (NativeRoutingEventHandlerDelegate delegate
                            : mRoutingChangeListeners.values()) {
                        delegate.notifyClient();
                    }
                }
                return;
            }

            default:
            {
                Log.e(TAG, "Unknown message type " + msg.what);
                return;
            }
            }
        }