mirror of
https://github.com/androidx/media.git
synced 2025-05-18 04:59:54 +08:00
Run DownloadManager on a custom thread while testing
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185674707
This commit is contained in:
parent
55f2b09340
commit
c8e950537d
@ -24,6 +24,7 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadListener;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadState;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadState.State;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.MockitoUtil;
|
||||
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
@ -53,12 +54,13 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
private DownloadManager downloadManager;
|
||||
private File actionFile;
|
||||
private TestDownloadListener testDownloadListener;
|
||||
private DummyMainThread dummyMainThread;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MockitoUtil.setUpMockito(this);
|
||||
|
||||
dummyMainThread = new DummyMainThread();
|
||||
actionFile = Util.createTempFile(getInstrumentation().getContext(), "ExoPlayerTest");
|
||||
testDownloadListener = new TestDownloadListener();
|
||||
setUpDownloadManager(100);
|
||||
@ -68,6 +70,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
public void tearDown() throws Exception {
|
||||
releaseDownloadManager();
|
||||
actionFile.delete();
|
||||
dummyMainThread.release();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@ -76,7 +79,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
releaseDownloadManager();
|
||||
}
|
||||
try {
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -98,7 +101,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
|
||||
private void releaseDownloadManager() throws Exception {
|
||||
try {
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -345,7 +348,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
remove2Action.post().assertStarted();
|
||||
download2Action.post().assertDoesNotStart();
|
||||
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -368,7 +371,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
// New download actions can be added but they don't start.
|
||||
download3Action.post().assertDoesNotStart();
|
||||
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -393,7 +396,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
// download3Action doesn't start as DM was configured to run two downloads in parallel.
|
||||
download3Action.post().assertDoesNotStart();
|
||||
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -404,7 +407,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
// download1Action doesn't stop yet as it ignores interrupts.
|
||||
download2Action.assertStopped();
|
||||
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -462,6 +465,10 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
return new FakeDownloadAction(mediaId, true);
|
||||
}
|
||||
|
||||
private void runOnMainThread(final Runnable r) throws Throwable {
|
||||
dummyMainThread.runOnMainThread(r);
|
||||
}
|
||||
|
||||
private static final class TestDownloadListener implements DownloadListener {
|
||||
|
||||
private ConditionVariable downloadFinishedCondition;
|
||||
@ -544,7 +551,7 @@ public class DownloadManagerTest extends InstrumentationTestCase {
|
||||
}
|
||||
|
||||
private FakeDownloadAction post() throws Throwable {
|
||||
runTestOnUiThread(
|
||||
runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -115,7 +115,12 @@ public final class DownloadManager {
|
||||
|
||||
tasks = new ArrayList<>();
|
||||
activeDownloadTasks = new ArrayList<>();
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
|
||||
Looper looper = Looper.myLooper();
|
||||
if (looper == null) {
|
||||
looper = Looper.getMainLooper();
|
||||
}
|
||||
handler = new Handler(looper);
|
||||
|
||||
fileIOThread = new HandlerThread("DownloadManager file i/o");
|
||||
fileIOThread.start();
|
||||
|
@ -20,13 +20,12 @@ import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.RobolectricUtil;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
||||
import com.google.android.exoplayer2.testutil.FakeShuffleOrder;
|
||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||
@ -779,40 +778,6 @@ public final class DynamicConcatenatingMediaSourceTest {
|
||||
return new FakeTimeline(new TimelineWindowDefinition(index + 1, (index + 1) * 111));
|
||||
}
|
||||
|
||||
private static final class DummyMainThread {
|
||||
|
||||
private final HandlerThread thread;
|
||||
private final Handler handler;
|
||||
|
||||
private DummyMainThread() {
|
||||
thread = new HandlerThread("DummyMainThread");
|
||||
thread.start();
|
||||
handler = new Handler(thread.getLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the provided {@link Runnable} on the main thread, blocking until execution completes.
|
||||
*
|
||||
* @param runnable The {@link Runnable} to run.
|
||||
*/
|
||||
public void runOnMainThread(final Runnable runnable) {
|
||||
final ConditionVariable finishedCondition = new ConditionVariable();
|
||||
handler.post(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runnable.run();
|
||||
finishedCondition.open();
|
||||
}
|
||||
});
|
||||
assertThat(finishedCondition.block(MediaSourceTestRunner.TIMEOUT_MS)).isTrue();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
thread.quit();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TimelineGrabber implements Runnable {
|
||||
|
||||
private final MediaSourceTestRunner testRunner;
|
||||
|
@ -28,6 +28,7 @@ import android.test.UiThreadTest;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource;
|
||||
import com.google.android.exoplayer2.testutil.MockitoUtil;
|
||||
@ -53,11 +54,13 @@ public class DownloadManagerDashTest extends InstrumentationTestCase {
|
||||
private RepresentationKey fakeRepresentationKey2;
|
||||
private TestDownloadListener downloadListener;
|
||||
private File actionFile;
|
||||
private DummyMainThread dummyMainThread;
|
||||
|
||||
@UiThreadTest
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
dummyMainThread = new DummyMainThread();
|
||||
Context context = getInstrumentation().getContext();
|
||||
tempFolder = Util.createTempDirectory(context, "ExoPlayerTest");
|
||||
File cacheFolder = new File(tempFolder, "cache");
|
||||
@ -85,6 +88,7 @@ public class DownloadManagerDashTest extends InstrumentationTestCase {
|
||||
public void tearDown() throws Exception {
|
||||
downloadManager.release();
|
||||
Util.recursiveDelete(tempFolder);
|
||||
dummyMainThread.release();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@ -111,7 +115,7 @@ public class DownloadManagerDashTest extends InstrumentationTestCase {
|
||||
|
||||
// Run DM accessing code on UI/main thread as it should be. Also not to block handling of loaded
|
||||
// actions.
|
||||
runTestOnUiThread(
|
||||
dummyMainThread.runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -226,18 +230,25 @@ public class DownloadManagerDashTest extends InstrumentationTestCase {
|
||||
}
|
||||
|
||||
private void createDownloadManager() {
|
||||
Factory fakeDataSourceFactory = new FakeDataSource.Factory(null).setFakeDataSet(fakeDataSet);
|
||||
downloadManager =
|
||||
new DownloadManager(
|
||||
new DownloaderConstructorHelper(cache, fakeDataSourceFactory),
|
||||
1,
|
||||
3,
|
||||
actionFile.getAbsolutePath(),
|
||||
DashDownloadAction.DESERIALIZER);
|
||||
dummyMainThread.runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Factory fakeDataSourceFactory =
|
||||
new FakeDataSource.Factory(null).setFakeDataSet(fakeDataSet);
|
||||
downloadManager =
|
||||
new DownloadManager(
|
||||
new DownloaderConstructorHelper(cache, fakeDataSourceFactory),
|
||||
1,
|
||||
3,
|
||||
actionFile.getAbsolutePath(),
|
||||
DashDownloadAction.DESERIALIZER);
|
||||
|
||||
downloadListener = new TestDownloadListener(downloadManager, this);
|
||||
downloadManager.addListener(downloadListener);
|
||||
downloadManager.startDownloads();
|
||||
downloadListener = new TestDownloadListener(downloadManager, dummyMainThread);
|
||||
downloadManager.addListener(downloadListener);
|
||||
downloadManager.startDownloads();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadService;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
@ -38,6 +39,7 @@ import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.android.exoplayer2.util.scheduler.Requirements;
|
||||
import com.google.android.exoplayer2.util.scheduler.Scheduler;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DownloadService}.
|
||||
@ -53,10 +55,12 @@ public class DownloadServiceDashTest extends InstrumentationTestCase {
|
||||
private DownloadService dashDownloadService;
|
||||
private ConditionVariable pauseDownloadCondition;
|
||||
private TestDownloadListener testDownloadListener;
|
||||
private DummyMainThread dummyMainThread;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
dummyMainThread = new DummyMainThread();
|
||||
tempFolder = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest");
|
||||
cache = new SimpleCache(tempFolder, new NoOpCacheEvictor());
|
||||
|
||||
@ -84,31 +88,36 @@ public class DownloadServiceDashTest extends InstrumentationTestCase {
|
||||
.setRandomData("text_segment_1", 1)
|
||||
.setRandomData("text_segment_2", 2)
|
||||
.setRandomData("text_segment_3", 3);
|
||||
DataSource.Factory fakeDataSourceFactory = new FakeDataSource.Factory(null)
|
||||
.setFakeDataSet(fakeDataSet);
|
||||
final DataSource.Factory fakeDataSourceFactory =
|
||||
new FakeDataSource.Factory(null).setFakeDataSet(fakeDataSet);
|
||||
fakeRepresentationKey1 = new RepresentationKey(0, 0, 0);
|
||||
fakeRepresentationKey2 = new RepresentationKey(0, 1, 0);
|
||||
|
||||
context = getInstrumentation().getContext();
|
||||
|
||||
File actionFile = Util.createTempFile(context, "ExoPlayerTest");
|
||||
actionFile.delete();
|
||||
final DownloadManager dashDownloadManager =
|
||||
new DownloadManager(
|
||||
new DownloaderConstructorHelper(cache, fakeDataSourceFactory),
|
||||
1,
|
||||
3,
|
||||
actionFile.getAbsolutePath(),
|
||||
DashDownloadAction.DESERIALIZER);
|
||||
testDownloadListener = new TestDownloadListener(dashDownloadManager, this);
|
||||
dashDownloadManager.addListener(testDownloadListener);
|
||||
dashDownloadManager.startDownloads();
|
||||
|
||||
try {
|
||||
runTestOnUiThread(
|
||||
dummyMainThread.runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
File actionFile = null;
|
||||
try {
|
||||
actionFile = Util.createTempFile(context, "ExoPlayerTest");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
actionFile.delete();
|
||||
final DownloadManager dashDownloadManager =
|
||||
new DownloadManager(
|
||||
new DownloaderConstructorHelper(cache, fakeDataSourceFactory),
|
||||
1,
|
||||
3,
|
||||
actionFile.getAbsolutePath(),
|
||||
DashDownloadAction.DESERIALIZER);
|
||||
testDownloadListener = new TestDownloadListener(dashDownloadManager, dummyMainThread);
|
||||
dashDownloadManager.addListener(testDownloadListener);
|
||||
dashDownloadManager.startDownloads();
|
||||
|
||||
dashDownloadService =
|
||||
new DownloadService(101010) {
|
||||
|
||||
@ -143,16 +152,18 @@ public class DownloadServiceDashTest extends InstrumentationTestCase {
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
try {
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dashDownloadService.onDestroy();
|
||||
}
|
||||
});
|
||||
dummyMainThread.runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dashDownloadService.onDestroy();
|
||||
}
|
||||
});
|
||||
} catch (Throwable throwable) {
|
||||
throw new Exception(throwable);
|
||||
}
|
||||
Util.recursiveDelete(tempFolder);
|
||||
dummyMainThread.release();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@ -197,7 +208,7 @@ public class DownloadServiceDashTest extends InstrumentationTestCase {
|
||||
}
|
||||
|
||||
private void callDownloadServiceOnStart(final DashDownloadAction action) throws Throwable {
|
||||
runTestOnUiThread(
|
||||
dummyMainThread.runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -17,10 +17,10 @@ package com.google.android.exoplayer2.source.dash.offline;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.test.InstrumentationTestCase;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadListener;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadState;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
|
||||
/** A {@link DownloadListener} for testing. */
|
||||
/*package*/ final class TestDownloadListener implements DownloadListener {
|
||||
@ -28,13 +28,13 @@ import com.google.android.exoplayer2.offline.DownloadManager.DownloadState;
|
||||
private static final int TIMEOUT = 1000;
|
||||
|
||||
private final DownloadManager downloadManager;
|
||||
private final InstrumentationTestCase testCase;
|
||||
private final DummyMainThread dummyMainThread;
|
||||
private final android.os.ConditionVariable downloadFinishedCondition;
|
||||
private Throwable downloadError;
|
||||
|
||||
public TestDownloadListener(DownloadManager downloadManager, InstrumentationTestCase testCase) {
|
||||
public TestDownloadListener(DownloadManager downloadManager, DummyMainThread dummyMainThread) {
|
||||
this.downloadManager = downloadManager;
|
||||
this.testCase = testCase;
|
||||
this.dummyMainThread = dummyMainThread;
|
||||
this.downloadFinishedCondition = new android.os.ConditionVariable();
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ import com.google.android.exoplayer2.offline.DownloadManager.DownloadState;
|
||||
* error.
|
||||
*/
|
||||
public void blockUntilTasksCompleteAndThrowAnyDownloadError() throws Throwable {
|
||||
testCase.runTestOnUiThread(
|
||||
dummyMainThread.runOnMainThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.testutil;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
|
||||
/** Helper class to simulate main/UI thread in tests. */
|
||||
public final class DummyMainThread {
|
||||
|
||||
/** Default timeout value used for {@link #runOnMainThread(Runnable)}. */
|
||||
public static final int TIMEOUT_MS = 10000;
|
||||
|
||||
private final HandlerThread thread;
|
||||
private final Handler handler;
|
||||
|
||||
public DummyMainThread() {
|
||||
thread = new HandlerThread("DummyMainThread");
|
||||
thread.start();
|
||||
handler = new Handler(thread.getLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the provided {@link Runnable} on the main thread, blocking until execution completes or
|
||||
* until {@link #TIMEOUT_MS} milliseconds have passed.
|
||||
*
|
||||
* @param runnable The {@link Runnable} to run.
|
||||
*/
|
||||
public void runOnMainThread(final Runnable runnable) {
|
||||
runOnMainThread(TIMEOUT_MS, runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the provided {@link Runnable} on the main thread, blocking until execution completes or
|
||||
* until timeout milliseconds have passed.
|
||||
*
|
||||
* @param timeoutMs the maximum time to wait in milliseconds.
|
||||
* @param runnable The {@link Runnable} to run.
|
||||
*/
|
||||
public void runOnMainThread(int timeoutMs, final Runnable runnable) {
|
||||
final ConditionVariable finishedCondition = new ConditionVariable();
|
||||
handler.post(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runnable.run();
|
||||
finishedCondition.open();
|
||||
}
|
||||
});
|
||||
assertThat(finishedCondition.block(timeoutMs)).isTrue();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
thread.quit();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user