Switch test usages of ConditionVariable#block(timeout) to CountDownLatch

ConditionVariable.block(timeout) doesn't work in Robolectric, because it
relies on the system clock which doesn't advance.

PiperOrigin-RevId: 275798281
This commit is contained in:
ibaker 2019-10-21 09:59:44 +01:00 committed by Oliver Woodman
parent 4e667b899d
commit 93f2dd8deb
6 changed files with 106 additions and 90 deletions

View File

@ -40,13 +40,14 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.ConditionVariable;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -412,21 +413,21 @@ public class DownloadHelperTest {
private static void prepareDownloadHelper(DownloadHelper downloadHelper) throws Exception { private static void prepareDownloadHelper(DownloadHelper downloadHelper) throws Exception {
AtomicReference<Exception> prepareException = new AtomicReference<>(null); AtomicReference<Exception> prepareException = new AtomicReference<>(null);
ConditionVariable preparedCondition = new ConditionVariable(); CountDownLatch preparedLatch = new CountDownLatch(1);
downloadHelper.prepare( downloadHelper.prepare(
new Callback() { new Callback() {
@Override @Override
public void onPrepared(DownloadHelper helper) { public void onPrepared(DownloadHelper helper) {
preparedCondition.open(); preparedLatch.countDown();
} }
@Override @Override
public void onPrepareError(DownloadHelper helper, IOException e) { public void onPrepareError(DownloadHelper helper, IOException e) {
prepareException.set(e); prepareException.set(e);
preparedCondition.open(); preparedLatch.countDown();
} }
}); });
while (!preparedCondition.block(0)) { while (!preparedLatch.await(0, TimeUnit.MILLISECONDS)) {
shadowMainLooper().idleFor(shadowMainLooper().getNextScheduledTaskTime()); shadowMainLooper().idleFor(shadowMainLooper().getNextScheduledTaskTime());
} }
if (prepareException.get() != null) { if (prepareException.get() != null) {

View File

@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
@ -39,6 +38,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -407,23 +407,23 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackBeforePreparationAddSingle() { public void testCustomCallbackBeforePreparationAddSingle() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
() -> () ->
mediaSource.addMediaSource( mediaSource.addMediaSource(
createFakeMediaSource(), new Handler(), runnableInvoked::open)); createFakeMediaSource(), new Handler(), runnableInvoked::countDown));
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
public void testCustomCallbackBeforePreparationAddMultiple() { public void testCustomCallbackBeforePreparationAddMultiple() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
@ -431,31 +431,31 @@ public final class ConcatenatingMediaSourceTest {
mediaSource.addMediaSources( mediaSource.addMediaSources(
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
new Handler(), new Handler(),
runnableInvoked::open)); runnableInvoked::countDown));
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
public void testCustomCallbackBeforePreparationAddSingleWithIndex() { public void testCustomCallbackBeforePreparationAddSingleWithIndex() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
() -> () ->
mediaSource.addMediaSource( mediaSource.addMediaSource(
/* index */ 0, createFakeMediaSource(), new Handler(), runnableInvoked::open)); /* index */ 0, createFakeMediaSource(), new Handler(), runnableInvoked::countDown));
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
public void testCustomCallbackBeforePreparationAddMultipleWithIndex() { public void testCustomCallbackBeforePreparationAddMultipleWithIndex() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
@ -464,32 +464,32 @@ public final class ConcatenatingMediaSourceTest {
/* index */ 0, /* index */ 0,
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
new Handler(), new Handler(),
runnableInvoked::open)); runnableInvoked::countDown));
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
public void testCustomCallbackBeforePreparationRemove() { public void testCustomCallbackBeforePreparationRemove() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
() -> { () -> {
mediaSource.addMediaSource(createFakeMediaSource()); mediaSource.addMediaSource(createFakeMediaSource());
mediaSource.removeMediaSource(/* index */ 0, new Handler(), runnableInvoked::open); mediaSource.removeMediaSource(/* index */ 0, new Handler(), runnableInvoked::countDown);
}); });
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
public void testCustomCallbackBeforePreparationMove() { public void testCustomCallbackBeforePreparationMove() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
@ -497,16 +497,16 @@ public final class ConcatenatingMediaSourceTest {
mediaSource.addMediaSources( mediaSource.addMediaSources(
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()})); Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}));
mediaSource.moveMediaSource( mediaSource.moveMediaSource(
/* fromIndex */ 1, /* toIndex */ 0, new Handler(), runnableInvoked::open); /* fromIndex */ 1, /* toIndex */ 0, new Handler(), runnableInvoked::countDown);
}); });
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
public void testCustomCallbackAfterPreparationAddSingle() throws IOException { public void testCustomCallbackAfterPreparationAddSingle() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
try { try {
testRunner.prepareSource(); testRunner.prepareSource();
@ -522,7 +522,7 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackAfterPreparationAddMultiple() throws IOException { public void testCustomCallbackAfterPreparationAddMultiple() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
try { try {
testRunner.prepareSource(); testRunner.prepareSource();
@ -542,7 +542,7 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackAfterPreparationAddSingleWithIndex() throws IOException { public void testCustomCallbackAfterPreparationAddSingleWithIndex() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
try { try {
testRunner.prepareSource(); testRunner.prepareSource();
@ -559,7 +559,7 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackAfterPreparationAddMultipleWithIndex() throws IOException { public void testCustomCallbackAfterPreparationAddMultipleWithIndex() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
try { try {
testRunner.prepareSource(); testRunner.prepareSource();
@ -580,7 +580,7 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackAfterPreparationRemove() throws IOException { public void testCustomCallbackAfterPreparationRemove() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
try { try {
testRunner.prepareSource(); testRunner.prepareSource();
@ -598,7 +598,7 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackAfterPreparationMove() throws IOException { public void testCustomCallbackAfterPreparationMove() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
try { try {
testRunner.prepareSource(); testRunner.prepareSource();
@ -622,9 +622,9 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testCustomCallbackIsCalledAfterRelease() throws IOException { public void testCustomCallbackIsCalledAfterRelease() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
ConditionVariable callbackCalledCondition = new ConditionVariable(); CountDownLatch callbackCalledCondition = new CountDownLatch(1);
try { try {
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
() -> { () -> {
@ -635,10 +635,13 @@ public final class ConcatenatingMediaSourceTest {
/* currentIndex= */ 0, /* currentIndex= */ 0,
/* newIndex= */ 1, /* newIndex= */ 1,
new Handler(), new Handler(),
callbackCalledCondition::open); callbackCalledCondition::countDown);
mediaSource.releaseSource(caller); mediaSource.releaseSource(caller);
}); });
assertThat(callbackCalledCondition.block(MediaSourceTestRunner.TIMEOUT_MS)).isTrue(); assertThat(
callbackCalledCondition.await(
MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS))
.isTrue();
} finally { } finally {
dummyMainThread.release(); dummyMainThread.release();
} }
@ -871,7 +874,7 @@ public final class ConcatenatingMediaSourceTest {
} }
@Test @Test
public void testClear() throws IOException { public void testClear() throws Exception {
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
final FakeMediaSource preparedChildSource = createFakeMediaSource(); final FakeMediaSource preparedChildSource = createFakeMediaSource();
final FakeMediaSource unpreparedChildSource = new FakeMediaSource(/* timeline= */ null); final FakeMediaSource unpreparedChildSource = new FakeMediaSource(/* timeline= */ null);
@ -1028,7 +1031,7 @@ public final class ConcatenatingMediaSourceTest {
@Test @Test
public void testCustomCallbackBeforePreparationSetShuffleOrder() throws Exception { public void testCustomCallbackBeforePreparationSetShuffleOrder() throws Exception {
ConditionVariable runnableInvoked = new ConditionVariable(); CountDownLatch runnableInvoked = new CountDownLatch(1);
DummyMainThread dummyMainThread = new DummyMainThread(); DummyMainThread dummyMainThread = new DummyMainThread();
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
@ -1036,11 +1039,11 @@ public final class ConcatenatingMediaSourceTest {
mediaSource.setShuffleOrder( mediaSource.setShuffleOrder(
new ShuffleOrder.UnshuffledShuffleOrder(/* length= */ 0), new ShuffleOrder.UnshuffledShuffleOrder(/* length= */ 0),
new Handler(), new Handler(),
runnableInvoked::open)); runnableInvoked::countDown));
runnableInvoked.block(MediaSourceTestRunner.TIMEOUT_MS); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS);
dummyMainThread.release(); dummyMainThread.release();
assertThat(runnableInvoked.block(0)).isTrue(); assertThat(runnableInvoked.getCount()).isEqualTo(0);
} }
@Test @Test
@ -1107,14 +1110,14 @@ public final class ConcatenatingMediaSourceTest {
private static final class TimelineGrabber implements Runnable { private static final class TimelineGrabber implements Runnable {
private final MediaSourceTestRunner testRunner; private final MediaSourceTestRunner testRunner;
private final ConditionVariable finishedCondition; private final CountDownLatch finishedLatch;
private Timeline timeline; private Timeline timeline;
private AssertionError error; private AssertionError error;
public TimelineGrabber(MediaSourceTestRunner testRunner) { public TimelineGrabber(MediaSourceTestRunner testRunner) {
this.testRunner = testRunner; this.testRunner = testRunner;
finishedCondition = new ConditionVariable(); finishedLatch = new CountDownLatch(1);
} }
@Override @Override
@ -1124,11 +1127,12 @@ public final class ConcatenatingMediaSourceTest {
} catch (AssertionError e) { } catch (AssertionError e) {
error = e; error = e;
} }
finishedCondition.open(); finishedLatch.countDown();
} }
public Timeline assertTimelineChangeBlocking() { public Timeline assertTimelineChangeBlocking() throws InterruptedException {
assertThat(finishedCondition.block(MediaSourceTestRunner.TIMEOUT_MS)).isTrue(); assertThat(finishedLatch.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS))
.isTrue();
if (error != null) { if (error != null) {
throw error; throw error;
} }

View File

@ -23,7 +23,6 @@ import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedDa
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.content.Context; import android.content.Context;
import android.os.ConditionVariable;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.offline.DefaultDownloadIndex; import com.google.android.exoplayer2.offline.DefaultDownloadIndex;
@ -47,6 +46,8 @@ import com.google.android.exoplayer2.util.Util;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
@ -61,7 +62,7 @@ import org.robolectric.shadows.ShadowLog;
@LooperMode(LooperMode.Mode.PAUSED) @LooperMode(LooperMode.Mode.PAUSED)
public class DownloadManagerDashTest { public class DownloadManagerDashTest {
private static final int ASSERT_TRUE_TIMEOUT = 1000; private static final int ASSERT_TRUE_TIMEOUT_MS = 1000;
private SimpleCache cache; private SimpleCache cache;
private File tempFolder; private File tempFolder;
@ -204,16 +205,17 @@ public class DownloadManagerDashTest {
@Test @Test
public void testHandleInterferingRemoveAction() throws Throwable { public void testHandleInterferingRemoveAction() throws Throwable {
final ConditionVariable downloadInProgressCondition = new ConditionVariable(); CountDownLatch downloadInProgressLatch = new CountDownLatch(1);
fakeDataSet fakeDataSet
.newData("audio_segment_2") .newData("audio_segment_2")
.appendReadAction(downloadInProgressCondition::open) .appendReadAction(downloadInProgressLatch::countDown)
.appendReadData(TestUtil.buildTestData(5)) .appendReadData(TestUtil.buildTestData(5))
.endData(); .endData();
handleDownloadRequest(fakeStreamKey1); handleDownloadRequest(fakeStreamKey1);
assertThat(downloadInProgressCondition.block(ASSERT_TRUE_TIMEOUT)).isTrue(); assertThat(downloadInProgressLatch.await(ASSERT_TRUE_TIMEOUT_MS, TimeUnit.MILLISECONDS))
.isTrue();
handleRemoveAction(); handleRemoveAction();
@ -261,7 +263,7 @@ public class DownloadManagerDashTest {
downloadManagerListener = downloadManagerListener =
new TestDownloadManagerListener( new TestDownloadManagerListener(
downloadManager, dummyMainThread, /* timeout= */ 3000); downloadManager, dummyMainThread, /* timeoutMs= */ 3000);
downloadManager.resumeDownloads(); downloadManager.resumeDownloads();
}); });
} }

View File

@ -17,11 +17,12 @@ package com.google.android.exoplayer2.testutil;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Looper; import android.os.Looper;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
/** Helper class to simulate main/UI thread in tests. */ /** Helper class to simulate main/UI thread in tests. */
@ -90,7 +91,7 @@ public final class DummyMainThread {
Util.sneakyThrow(e); Util.sneakyThrow(e);
} }
} else { } else {
ConditionVariable finishedCondition = new ConditionVariable(); CountDownLatch finishedLatch = new CountDownLatch(1);
AtomicReference<Throwable> thrown = new AtomicReference<>(); AtomicReference<Throwable> thrown = new AtomicReference<>();
handler.post( handler.post(
() -> { () -> {
@ -99,9 +100,13 @@ public final class DummyMainThread {
} catch (Throwable t) { } catch (Throwable t) {
thrown.set(t); thrown.set(t);
} }
finishedCondition.open(); finishedLatch.countDown();
}); });
assertThat(finishedCondition.block(timeoutMs)).isTrue(); try {
assertThat(finishedLatch.await(timeoutMs, TimeUnit.MILLISECONDS)).isTrue();
} catch (InterruptedException e) {
Util.sneakyThrow(e);
}
if (thrown.get() != null) { if (thrown.get() != null) {
Util.sneakyThrow(thrown.get()); Util.sneakyThrow(thrown.get());
} }

View File

@ -89,8 +89,8 @@ public class MediaSourceTestRunner {
* @param runnable The {@link Runnable} to run. * @param runnable The {@link Runnable} to run.
*/ */
public void runOnPlaybackThread(final Runnable runnable) { public void runOnPlaybackThread(final Runnable runnable) {
final Throwable[] throwable = new Throwable[1]; Throwable[] throwable = new Throwable[1];
final ConditionVariable finishedCondition = new ConditionVariable(); CountDownLatch finishedLatch = new CountDownLatch(1);
playbackHandler.post( playbackHandler.post(
() -> { () -> {
try { try {
@ -98,10 +98,14 @@ public class MediaSourceTestRunner {
} catch (Throwable e) { } catch (Throwable e) {
throwable[0] = e; throwable[0] = e;
} finally { } finally {
finishedCondition.open(); finishedLatch.countDown();
} }
}); });
assertThat(finishedCondition.block(TIMEOUT_MS)).isTrue(); try {
assertThat(finishedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
} catch (InterruptedException e) {
Util.sneakyThrow(e);
}
if (throwable[0] != null) { if (throwable[0] != null) {
Util.sneakyThrow(throwable[0]); Util.sneakyThrow(throwable[0]);
} }
@ -169,14 +173,14 @@ public class MediaSourceTestRunner {
*/ */
public CountDownLatch preparePeriod(final MediaPeriod mediaPeriod, final long positionUs) { public CountDownLatch preparePeriod(final MediaPeriod mediaPeriod, final long positionUs) {
final ConditionVariable prepareCalled = new ConditionVariable(); final ConditionVariable prepareCalled = new ConditionVariable();
final CountDownLatch preparedCountDown = new CountDownLatch(1); final CountDownLatch preparedLatch = new CountDownLatch(1);
runOnPlaybackThread( runOnPlaybackThread(
() -> { () -> {
mediaPeriod.prepare( mediaPeriod.prepare(
new MediaPeriod.Callback() { new MediaPeriod.Callback() {
@Override @Override
public void onPrepared(MediaPeriod mediaPeriod1) { public void onPrepared(MediaPeriod mediaPeriod1) {
preparedCountDown.countDown(); preparedLatch.countDown();
} }
@Override @Override
@ -188,7 +192,7 @@ public class MediaSourceTestRunner {
prepareCalled.open(); prepareCalled.open();
}); });
prepareCalled.block(); prepareCalled.block();
return preparedCountDown; return preparedLatch;
} }
/** /**
@ -267,8 +271,8 @@ public class MediaSourceTestRunner {
throws InterruptedException { throws InterruptedException {
MediaPeriod mediaPeriod = createPeriod(mediaPeriodId); MediaPeriod mediaPeriod = createPeriod(mediaPeriodId);
assertThat(lastCreatedMediaPeriod.getAndSet(/* newValue= */ null)).isEqualTo(mediaPeriodId); assertThat(lastCreatedMediaPeriod.getAndSet(/* newValue= */ null)).isEqualTo(mediaPeriodId);
CountDownLatch preparedCondition = preparePeriod(mediaPeriod, 0); CountDownLatch preparedLatch = preparePeriod(mediaPeriod, 0);
assertThat(preparedCondition.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue(); assertThat(preparedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
// MediaSource is supposed to support multiple calls to createPeriod without an intervening call // MediaSource is supposed to support multiple calls to createPeriod without an intervening call
// to releasePeriod. // to releasePeriod.
MediaPeriodId secondMediaPeriodId = MediaPeriodId secondMediaPeriodId =
@ -280,8 +284,8 @@ public class MediaSourceTestRunner {
MediaPeriod secondMediaPeriod = createPeriod(secondMediaPeriodId); MediaPeriod secondMediaPeriod = createPeriod(secondMediaPeriodId);
assertThat(lastCreatedMediaPeriod.getAndSet(/* newValue= */ null)) assertThat(lastCreatedMediaPeriod.getAndSet(/* newValue= */ null))
.isEqualTo(secondMediaPeriodId); .isEqualTo(secondMediaPeriodId);
CountDownLatch secondPreparedCondition = preparePeriod(secondMediaPeriod, 0); CountDownLatch secondPreparedLatch = preparePeriod(secondMediaPeriod, 0);
assertThat(secondPreparedCondition.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue(); assertThat(secondPreparedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
// Release the periods. // Release the periods.
releasePeriod(mediaPeriod); releasePeriod(mediaPeriod);
assertThat(lastReleasedMediaPeriod.getAndSet(/* newValue= */ null)).isEqualTo(mediaPeriodId); assertThat(lastReleasedMediaPeriod.getAndSet(/* newValue= */ null)).isEqualTo(mediaPeriodId);

View File

@ -18,7 +18,6 @@ package com.google.android.exoplayer2.testutil;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import android.os.ConditionVariable;
import com.google.android.exoplayer2.offline.Download; import com.google.android.exoplayer2.offline.Download;
import com.google.android.exoplayer2.offline.Download.State; import com.google.android.exoplayer2.offline.Download.State;
import com.google.android.exoplayer2.offline.DownloadManager; import com.google.android.exoplayer2.offline.DownloadManager;
@ -30,31 +29,31 @@ import java.util.concurrent.TimeUnit;
/** A {@link DownloadManager.Listener} for testing. */ /** A {@link DownloadManager.Listener} for testing. */
public final class TestDownloadManagerListener implements DownloadManager.Listener { public final class TestDownloadManagerListener implements DownloadManager.Listener {
private static final int TIMEOUT = 1000; private static final int TIMEOUT_MS = 1000;
private static final int INITIALIZATION_TIMEOUT = 10000; private static final int INITIALIZATION_TIMEOUT_MS = 10_000;
private static final int STATE_REMOVED = -1; private static final int STATE_REMOVED = -1;
private final DownloadManager downloadManager; private final DownloadManager downloadManager;
private final DummyMainThread dummyMainThread; private final DummyMainThread dummyMainThread;
private final HashMap<String, ArrayBlockingQueue<Integer>> downloadStates; private final HashMap<String, ArrayBlockingQueue<Integer>> downloadStates;
private final ConditionVariable initializedCondition; private final CountDownLatch initializedCondition;
private final int timeout; private final int timeoutMs;
private CountDownLatch downloadFinishedCondition; private CountDownLatch downloadFinishedCondition;
@Download.FailureReason private int failureReason; @Download.FailureReason private int failureReason;
public TestDownloadManagerListener( public TestDownloadManagerListener(
DownloadManager downloadManager, DummyMainThread dummyMainThread) { DownloadManager downloadManager, DummyMainThread dummyMainThread) {
this(downloadManager, dummyMainThread, TIMEOUT); this(downloadManager, dummyMainThread, TIMEOUT_MS);
} }
public TestDownloadManagerListener( public TestDownloadManagerListener(
DownloadManager downloadManager, DummyMainThread dummyMainThread, int timeout) { DownloadManager downloadManager, DummyMainThread dummyMainThread, int timeoutMs) {
this.downloadManager = downloadManager; this.downloadManager = downloadManager;
this.dummyMainThread = dummyMainThread; this.dummyMainThread = dummyMainThread;
this.timeout = timeout; this.timeoutMs = timeoutMs;
downloadStates = new HashMap<>(); downloadStates = new HashMap<>();
initializedCondition = new ConditionVariable(); initializedCondition = new CountDownLatch(1);
downloadManager.addListener(this); downloadManager.addListener(this);
} }
@ -64,12 +63,13 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
@Override @Override
public void onInitialized(DownloadManager downloadManager) { public void onInitialized(DownloadManager downloadManager) {
initializedCondition.open(); initializedCondition.countDown();
} }
public void waitUntilInitialized() { public void waitUntilInitialized() throws InterruptedException {
if (!downloadManager.isInitialized()) { if (!downloadManager.isInitialized()) {
assertThat(initializedCondition.block(INITIALIZATION_TIMEOUT)).isTrue(); assertThat(initializedCondition.await(INITIALIZATION_TIMEOUT_MS, TimeUnit.MILLISECONDS))
.isTrue();
} }
} }
@ -115,7 +115,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
downloadFinishedCondition.countDown(); downloadFinishedCondition.countDown();
} }
}); });
assertThat(downloadFinishedCondition.await(timeout, TimeUnit.MILLISECONDS)).isTrue(); assertThat(downloadFinishedCondition.await(timeoutMs, TimeUnit.MILLISECONDS)).isTrue();
} }
private ArrayBlockingQueue<Integer> getStateQueue(String taskId) { private ArrayBlockingQueue<Integer> getStateQueue(String taskId) {