From 0b608dd19c872f40e3907bc8ad20749e9596fc28 Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 11 Jun 2020 14:17:40 +0100 Subject: [PATCH] Fix order of events in ProgressiveMediaPeriod. The order of source info refresh and onPrepared was accidentally changed by https://github.com/google/ExoPlayer/commit/ed88f4f1dd7addc9932094113f560287ea7d344e. This changes it back to the correct order and adds a test PiperOrigin-RevId: 315885164 --- .../source/ProgressiveMediaPeriod.java | 6 +- .../source/ProgressiveMediaPeriodTest.java | 80 +++++++++++++++++++ 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 library/core/src/test/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriodTest.java diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java index 1e48d95bee..d879671c83 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java @@ -734,13 +734,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private void setSeekMap(SeekMap seekMap) { this.seekMap = icyHeaders == null ? seekMap : new Unseekable(/* durationUs= */ C.TIME_UNSET); - if (!prepared) { - maybeFinishPrepare(); - } durationUs = seekMap.getDurationUs(); isLive = length == C.LENGTH_UNSET && seekMap.getDurationUs() == C.TIME_UNSET; dataType = isLive ? C.DATA_TYPE_MEDIA_PROGRESSIVE_LIVE : C.DATA_TYPE_MEDIA; listener.onSourceInfoRefreshed(durationUs, seekMap.isSeekable(), isLive); + if (!prepared) { + maybeFinishPrepare(); + } } private void maybeFinishPrepare() { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriodTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriodTest.java new file mode 100644 index 0000000000..0478f77367 --- /dev/null +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriodTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.source; + +import static com.google.common.truth.Truth.assertThat; + +import android.net.Uri; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.drm.DrmSessionManager; +import com.google.android.exoplayer2.extractor.Extractor; +import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor; +import com.google.android.exoplayer2.testutil.TestExoPlayer; +import com.google.android.exoplayer2.upstream.AssetDataSource; +import com.google.android.exoplayer2.upstream.DefaultAllocator; +import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.LooperMode; + +/** Unit test for {@link ProgressiveMediaPeriod}. */ +@RunWith(AndroidJUnit4.class) +@LooperMode(LooperMode.Mode.PAUSED) +public final class ProgressiveMediaPeriodTest { + + @Test + public void prepare_updatesSourceInfoBeforeOnPreparedCallback() throws Exception { + AtomicBoolean sourceInfoRefreshCalled = new AtomicBoolean(false); + ProgressiveMediaPeriod.Listener sourceInfoRefreshListener = + (durationUs, isSeekable, isLive) -> sourceInfoRefreshCalled.set(true); + ProgressiveMediaPeriod mediaPeriod = + new ProgressiveMediaPeriod( + Uri.parse("asset://android_asset/mp4/sample.mp4"), + new AssetDataSource(ApplicationProvider.getApplicationContext()), + () -> new Extractor[] {new Mp4Extractor()}, + DrmSessionManager.DUMMY, + new DefaultLoadErrorHandlingPolicy(), + new MediaSourceEventListener.EventDispatcher(), + sourceInfoRefreshListener, + new DefaultAllocator(/* trimOnReset= */ true, C.DEFAULT_BUFFER_SEGMENT_SIZE), + /* customCacheKey= */ null, + ProgressiveMediaSource.DEFAULT_LOADING_CHECK_INTERVAL_BYTES); + + AtomicBoolean prepareCallbackCalled = new AtomicBoolean(false); + AtomicBoolean sourceInfoRefreshCalledBeforeOnPrepared = new AtomicBoolean(false); + mediaPeriod.prepare( + new MediaPeriod.Callback() { + @Override + public void onPrepared(MediaPeriod mediaPeriod) { + sourceInfoRefreshCalledBeforeOnPrepared.set(sourceInfoRefreshCalled.get()); + prepareCallbackCalled.set(true); + } + + @Override + public void onContinueLoadingRequested(MediaPeriod source) { + source.continueLoading(/* positionUs= */ 0); + } + }, + /* positionUs= */ 0); + TestExoPlayer.runUntil(prepareCallbackCalled::get); + mediaPeriod.release(); + + assertThat(sourceInfoRefreshCalledBeforeOnPrepared.get()).isTrue(); + } +}