Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08827e4b authored by Wei Jia's avatar Wei Jia
Browse files

MediaPlayer2: fix MEDIA_INFO_DATA_SOURCE_* events

Test: cts test
Bug: 109928575
Change-Id: Id333c9447f3621147afff21ee375340e0e6be5ce
parent 3de85266
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -1794,18 +1794,17 @@ public abstract class MediaPlayer2 implements SubtitleController.Listener
    public @interface MediaError {}
    public @interface MediaError {}


    /* Do not change these values without updating their counterparts
    /* Do not change these values without updating their counterparts
     * in include/media/mediaplayer2.h!
     * in include/media/MediaPlayer2Types.h!
     */
     */
    /** Unspecified media player info.
    /** Unspecified media player info.
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     */
     */
    public static final int MEDIA_INFO_UNKNOWN = 1;
    public static final int MEDIA_INFO_UNKNOWN = 1;


    /** The player switched to this datas source because it is the
    /** The player just started the playback of this datas source.
     * next-to-be-played in the playlist.
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     */
     */
    public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
    public static final int MEDIA_INFO_DATA_SOURCE_START = 2;


    /** The player just pushed the very first video frame for rendering.
    /** The player just pushed the very first video frame for rendering.
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     * @see android.media.MediaPlayer2.EventCallback#onInfo
@@ -1820,12 +1819,13 @@ public abstract class MediaPlayer2 implements SubtitleController.Listener
    /** The player just completed the playback of this data source.
    /** The player just completed the playback of this data source.
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     */
     */
    public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5;
    public static final int MEDIA_INFO_DATA_SOURCE_END = 5;


    /** The player just completed the playback of the full playlist.
    /** The player just completed the playback of all data sources set by {@link #setDataSource},
     * {@link #setNextDataSource} and {@link #setNextDataSources}.
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     */
     */
    public static final int MEDIA_INFO_PLAYLIST_END = 6;
    public static final int MEDIA_INFO_DATA_SOURCE_LIST_END = 6;


    /** The player just prepared a data source.
    /** The player just prepared a data source.
     * @see android.media.MediaPlayer2.EventCallback#onInfo
     * @see android.media.MediaPlayer2.EventCallback#onInfo
@@ -1927,11 +1927,11 @@ public abstract class MediaPlayer2 implements SubtitleController.Listener
     */
     */
    @IntDef(flag = false, prefix = "MEDIA_INFO", value = {
    @IntDef(flag = false, prefix = "MEDIA_INFO", value = {
            MEDIA_INFO_UNKNOWN,
            MEDIA_INFO_UNKNOWN,
            MEDIA_INFO_STARTED_AS_NEXT,
            MEDIA_INFO_DATA_SOURCE_START,
            MEDIA_INFO_VIDEO_RENDERING_START,
            MEDIA_INFO_VIDEO_RENDERING_START,
            MEDIA_INFO_AUDIO_RENDERING_START,
            MEDIA_INFO_AUDIO_RENDERING_START,
            MEDIA_INFO_PLAYBACK_COMPLETE,
            MEDIA_INFO_DATA_SOURCE_END,
            MEDIA_INFO_PLAYLIST_END,
            MEDIA_INFO_DATA_SOURCE_LIST_END,
            MEDIA_INFO_PREPARED,
            MEDIA_INFO_PREPARED,
            MEDIA_INFO_VIDEO_TRACK_LAGGING,
            MEDIA_INFO_VIDEO_TRACK_LAGGING,
            MEDIA_INFO_BUFFERING_START,
            MEDIA_INFO_BUFFERING_START,
+93 −58
Original line number Original line Diff line number Diff line
@@ -210,6 +210,22 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
            @Override
            @Override
            void process() {
            void process() {
                stayAwake(true);
                stayAwake(true);

                // TODO: remove this block when native code sends MEDIA_INFO_DATA_SOURCE_START
                // when pipeline is created.
                if (getState() == PLAYER_STATE_PREPARED) {
                    final DataSourceDesc dsd;
                    synchronized (mSrcLock) {
                        dsd = mCurrentDSD;
                    }
                    synchronized (mEventCbLock) {
                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                            cb.first.execute(() -> cb.second.onInfo(
                                    MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
                        }
                    }
                }

                _start();
                _start();
            }
            }
        });
        });
@@ -246,6 +262,22 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
            @Override
            @Override
            void process() {
            void process() {
                stayAwake(false);
                stayAwake(false);

                // TODO: remove this block when native code allows prepared -> pause
                // and sends MEDIA_INFO_DATA_SOURCE_START when pipeline is created.
                if (getState() == PLAYER_STATE_PREPARED) {
                    final DataSourceDesc dsd;
                    synchronized (mSrcLock) {
                        dsd = mCurrentDSD;
                    }
                    synchronized (mEventCbLock) {
                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                            cb.first.execute(() -> cb.second.onInfo(
                                    MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
                        }
                    }
                }

                _pause();
                _pause();
            }
            }
        });
        });
@@ -888,23 +920,30 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
    private native void nativeHandleDataSourceCallback(
    private native void nativeHandleDataSourceCallback(
            boolean isCurrent, long srcId, Media2DataSource dataSource);
            boolean isCurrent, long srcId, Media2DataSource dataSource);


    /**
     * @return true if there is a next data source, false otherwise.
     */
    // This function should be always called on |mHandlerThread|.
    // This function should be always called on |mHandlerThread|.
    private void prepareNextDataSource() {
    private boolean prepareNextDataSource() {
        if (Looper.myLooper() != mHandlerThread.getLooper()) {
        if (Looper.myLooper() != mHandlerThread.getLooper()) {
            Log.e(TAG, "prepareNextDataSource: called on wrong looper");
            Log.e(TAG, "prepareNextDataSource: called on wrong looper");
        }
        }


        boolean hasNextDSD;
        synchronized (mSrcLock) {
            hasNextDSD = (mNextDSDs != null && !mNextDSDs.isEmpty());
        }

        int state = getState();
        int state = getState();
        if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) {
        if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) {
            // Current source has not been prepared yet.
            // Current source has not been prepared yet.
            return;
            return hasNextDSD;
        }
        }


        synchronized (mSrcLock) {
        synchronized (mSrcLock) {
            if (mNextDSDs == null || mNextDSDs.isEmpty()
            if (!hasNextDSD || mNextSourceState != NEXT_SOURCE_STATE_INIT) {
                    || mNextSourceState != NEXT_SOURCE_STATE_INIT) {
                // There is no next source or it's in preparing or prepared state.
                // There is no next source or it's in preparing or prepared state.
                return;
                return hasNextDSD;
            }
            }


            try {
            try {
@@ -919,9 +958,10 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
                // make a new SrcId to obsolete notification for previous one.
                // make a new SrcId to obsolete notification for previous one.
                mNextSrcId = mSrcIdGenerator++;
                mNextSrcId = mSrcIdGenerator++;
                mNextSourceState = NEXT_SOURCE_STATE_INIT;
                mNextSourceState = NEXT_SOURCE_STATE_INIT;
                prepareNextDataSource();
                return prepareNextDataSource();
            }
            }
        }
        }
        return hasNextDSD;
    }
    }


    // This function should be always called on |mHandlerThread|.
    // This function should be always called on |mHandlerThread|.
@@ -930,11 +970,10 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
            Log.e(TAG, "playNextDataSource: called on wrong looper");
            Log.e(TAG, "playNextDataSource: called on wrong looper");
        }
        }


        boolean hasNextDSD = false;
        synchronized (mSrcLock) {
        synchronized (mSrcLock) {
            if (mNextDSDs == null || mNextDSDs.isEmpty()) {
            if (mNextDSDs != null && !mNextDSDs.isEmpty()) {
                return;
                hasNextDSD = true;
            }

                if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
                if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
                    // Switch to next source only when it has been prepared.
                    // Switch to next source only when it has been prepared.
                    mCurrentDSD = mNextDSDs.get(0);
                    mCurrentDSD = mNextDSDs.get(0);
@@ -953,17 +992,26 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
                                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
                                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
                        mTaskHandler.handleMessage(msg2, srcId);
                        mTaskHandler.handleMessage(msg2, srcId);
                        // Keep |mNextSourcePlayPending|
                        // Keep |mNextSourcePlayPending|
                    prepareNextDataSource();
                        hasNextDSD = prepareNextDataSource();
                    return;
                    }
                    }
                    if (hasNextDSD) {
                        stayAwake(true);
                        stayAwake(true);


                        // Now a new current src is playing.
                        // Now a new current src is playing.
                // Wait for MEDIA2_INFO_STARTED_AS_NEXT to prepare next source.
                        // Wait for MEDIA_INFO_DATA_SOURCE_START to prepare next source.
                        mNextSourcePlayPending = false;
                        mNextSourcePlayPending = false;
            } else {
                    }
                if (mNextSourceState == NEXT_SOURCE_STATE_INIT) {
                } else if (mNextSourceState == NEXT_SOURCE_STATE_INIT) {
                    prepareNextDataSource();
                    hasNextDSD = prepareNextDataSource();
                }
            }
        }

        if (!hasNextDSD) {
            synchronized (mEventCbLock) {
                for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                    cb.first.execute(() -> cb.second.onInfo(
                            MediaPlayer2Impl.this, null, MEDIA_INFO_DATA_SOURCE_LIST_END, 0));
                }
                }
            }
            }
        }
        }
@@ -2767,7 +2815,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
                    synchronized (mEventCbLock) {
                    synchronized (mEventCbLock) {
                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                        for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                            cb.first.execute(() -> cb.second.onInfo(
                            cb.first.execute(() -> cb.second.onInfo(
                                    mMediaPlayer, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
                                    mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
                        }
                        }
                    }
                    }
                    stayAwake(false);
                    stayAwake(false);
@@ -2869,7 +2917,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
                        cb.first.execute(() -> cb.second.onError(
                        cb.first.execute(() -> cb.second.onError(
                                mMediaPlayer, dsd, what, extra));
                                mMediaPlayer, dsd, what, extra));
                        cb.first.execute(() -> cb.second.onInfo(
                        cb.first.execute(() -> cb.second.onInfo(
                                mMediaPlayer, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
                                mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
                    }
                    }
                }
                }
                stayAwake(false);
                stayAwake(false);
@@ -2878,8 +2926,15 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {


            case MEDIA_INFO:
            case MEDIA_INFO:
            {
            {
                synchronized (mEventCbLock) {
                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onInfo(
                                mMediaPlayer, dsd, what, extra));
                    }
                }

                switch (msg.arg1) {
                switch (msg.arg1) {
                    case MEDIA_INFO_STARTED_AS_NEXT:
                    case MEDIA_INFO_DATA_SOURCE_START:
                        if (isCurrentSrcId) {
                        if (isCurrentSrcId) {
                            prepareNextDataSource();
                            prepareNextDataSource();
                        }
                        }
@@ -2916,13 +2971,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
                        }
                        }
                        break;
                        break;
                }
                }

                synchronized (mEventCbLock) {
                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
                        cb.first.execute(() -> cb.second.onInfo(
                                mMediaPlayer, dsd, what, extra));
                    }
                }
                // No real default action so far.
                // No real default action so far.
                return;
                return;
            }
            }
@@ -3034,19 +3082,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
        }
        }


        switch (what) {
        switch (what) {
        case MEDIA_INFO:
            if (arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // this acquires the wakelock if needed, and sets the client side state
                        mp.play();
                    }
                }).start();
                Thread.yield();
            }
            break;

        case MEDIA_DRM_INFO:
        case MEDIA_DRM_INFO:
            // We need to derive mDrmInfoImpl before prepare() returns so processing it here
            // We need to derive mDrmInfoImpl before prepare() returns so processing it here
            // before the notification is sent to TaskHandler below. TaskHandler runs in the
            // before the notification is sent to TaskHandler below. TaskHandler runs in the