Skip to content

Commit e3018e5

Browse files
tianyifcopybara-github
authored andcommitted
Move FakeDownloader to test-utils-robolectric for reuse in other tests
This could be useful for enhancing PreCacheHelperTest. PiperOrigin-RevId: 761549917
1 parent 3e57cad commit e3018e5

File tree

3 files changed

+170
-125
lines changed

3 files changed

+170
-125
lines changed

RELEASENOTES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
`TestPlayerRunHelper` in order to advance the player until a specified
6464
position is reached. In most cases, these methods are more reliable than
6565
the existing `untilPosition` and `untilStartOfMediaItem` methods.
66+
* Move `FakeDownloader` to `test-utils-robolectric` module for reuse in
67+
other tests.
6668
* Remove deprecated symbols:
6769

6870
## 1.8

libraries/exoplayer/src/test/java/androidx/media3/exoplayer/offline/DownloadManagerTest.java

Lines changed: 1 addition & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,26 @@
1515
*/
1616
package androidx.media3.exoplayer.offline;
1717

18-
import static androidx.media3.test.utils.robolectric.RobolectricUtil.createRobolectricConditionVariable;
1918
import static com.google.common.truth.Truth.assertThat;
2019
import static java.util.Arrays.asList;
2120

2221
import android.net.Uri;
2322
import androidx.annotation.GuardedBy;
2423
import androidx.annotation.Nullable;
25-
import androidx.media3.common.C;
2624
import androidx.media3.common.StreamKey;
2725
import androidx.media3.common.util.Assertions;
28-
import androidx.media3.common.util.ConditionVariable;
2926
import androidx.media3.exoplayer.scheduler.Requirements;
3027
import androidx.media3.test.utils.DownloadBuilder;
3128
import androidx.media3.test.utils.DummyMainThread;
3229
import androidx.media3.test.utils.DummyMainThread.TestRunnable;
3330
import androidx.media3.test.utils.TestUtil;
31+
import androidx.media3.test.utils.robolectric.FakeDownloader;
3432
import androidx.media3.test.utils.robolectric.TestDownloadManagerListener;
3533
import androidx.test.core.app.ApplicationProvider;
3634
import androidx.test.ext.junit.runners.AndroidJUnit4;
3735
import java.io.IOException;
3836
import java.util.ArrayList;
3937
import java.util.List;
40-
import java.util.concurrent.atomic.AtomicInteger;
4138
import java.util.concurrent.atomic.AtomicReference;
4239
import org.junit.After;
4340
import org.junit.Before;
@@ -912,125 +909,4 @@ public Downloader createDownloader(DownloadRequest request) {
912909
return fakeDownloader;
913910
}
914911
}
915-
916-
private static final class FakeDownloader implements Downloader {
917-
918-
private final DownloadRequest request;
919-
private final ConditionVariable downloadStarted;
920-
private final ConditionVariable removeStarted;
921-
private final ConditionVariable finished;
922-
private final ConditionVariable blocker;
923-
private final AtomicInteger startCount;
924-
private final AtomicInteger bytesDownloaded;
925-
926-
private volatile boolean canceled;
927-
private volatile boolean enableDownloadIOException;
928-
929-
private FakeDownloader(DownloadRequest request) {
930-
this.request = request;
931-
downloadStarted = createRobolectricConditionVariable();
932-
removeStarted = createRobolectricConditionVariable();
933-
finished = createRobolectricConditionVariable();
934-
blocker = createRobolectricConditionVariable();
935-
startCount = new AtomicInteger();
936-
bytesDownloaded = new AtomicInteger();
937-
}
938-
939-
@Override
940-
public void cancel() {
941-
canceled = true;
942-
blocker.open();
943-
}
944-
945-
@Override
946-
public void download(ProgressListener listener) throws IOException {
947-
startCount.incrementAndGet();
948-
downloadStarted.open();
949-
try {
950-
block();
951-
if (canceled) {
952-
return;
953-
}
954-
int bytesDownloaded = this.bytesDownloaded.get();
955-
if (listener != null && bytesDownloaded > 0) {
956-
listener.onProgress(C.LENGTH_UNSET, bytesDownloaded, C.PERCENTAGE_UNSET);
957-
}
958-
if (enableDownloadIOException) {
959-
enableDownloadIOException = false;
960-
throw new IOException();
961-
}
962-
} finally {
963-
finished.open();
964-
}
965-
}
966-
967-
@Override
968-
public void remove() {
969-
startCount.incrementAndGet();
970-
removeStarted.open();
971-
try {
972-
block();
973-
} finally {
974-
finished.open();
975-
}
976-
}
977-
978-
/** Finishes the {@link #download} or {@link #remove} without an error. */
979-
public void finish() throws InterruptedException {
980-
blocker.open();
981-
blockUntilFinished();
982-
}
983-
984-
/** Fails {@link #download} or {@link #remove} with an error. */
985-
public void fail() throws InterruptedException {
986-
enableDownloadIOException = true;
987-
blocker.open();
988-
blockUntilFinished();
989-
}
990-
991-
/** Increments the number of bytes that the fake downloader has downloaded. */
992-
public void incrementBytesDownloaded() {
993-
bytesDownloaded.incrementAndGet();
994-
}
995-
996-
public void assertId(String id) {
997-
assertThat(request.id).isEqualTo(id);
998-
}
999-
1000-
public void assertStreamKeys(StreamKey... streamKeys) {
1001-
assertThat(request.streamKeys).containsExactlyElementsIn(streamKeys);
1002-
}
1003-
1004-
public void assertDownloadStarted() throws InterruptedException {
1005-
assertThat(downloadStarted.block(TIMEOUT_MS)).isTrue();
1006-
downloadStarted.close();
1007-
}
1008-
1009-
public void assertRemoveStarted() throws InterruptedException {
1010-
assertThat(removeStarted.block(TIMEOUT_MS)).isTrue();
1011-
removeStarted.close();
1012-
}
1013-
1014-
public void assertCanceled() throws InterruptedException {
1015-
blockUntilFinished();
1016-
assertThat(canceled).isTrue();
1017-
}
1018-
1019-
// Internal methods.
1020-
1021-
private void block() {
1022-
try {
1023-
blocker.block();
1024-
} catch (InterruptedException e) {
1025-
throw new IllegalStateException(e); // Never happens.
1026-
} finally {
1027-
blocker.close();
1028-
}
1029-
}
1030-
1031-
private void blockUntilFinished() throws InterruptedException {
1032-
assertThat(finished.block(TIMEOUT_MS)).isTrue();
1033-
finished.close();
1034-
}
1035-
}
1036912
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package androidx.media3.test.utils.robolectric;
17+
18+
import static androidx.media3.test.utils.robolectric.RobolectricUtil.createRobolectricConditionVariable;
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import androidx.annotation.Nullable;
22+
import androidx.media3.common.C;
23+
import androidx.media3.common.StreamKey;
24+
import androidx.media3.common.util.ConditionVariable;
25+
import androidx.media3.common.util.UnstableApi;
26+
import androidx.media3.exoplayer.offline.DownloadRequest;
27+
import androidx.media3.exoplayer.offline.Downloader;
28+
import java.io.IOException;
29+
import java.util.concurrent.atomic.AtomicInteger;
30+
31+
/** A fake {@link Downloader}. */
32+
@UnstableApi
33+
public class FakeDownloader implements Downloader {
34+
35+
/** Timeout to use when blocking on conditions that we expect to become unblocked. */
36+
private static final int TIMEOUT_MS = 10_000;
37+
38+
private final DownloadRequest request;
39+
private final ConditionVariable downloadStarted;
40+
private final ConditionVariable removeStarted;
41+
private final ConditionVariable finished;
42+
private final ConditionVariable blocker;
43+
private final AtomicInteger startCount;
44+
private final AtomicInteger bytesDownloaded;
45+
46+
private volatile boolean canceled;
47+
private volatile boolean enableDownloadIoException;
48+
49+
/**
50+
* Creates a {@link FakeDownloader}.
51+
*
52+
* @param request The {@linkplain DownloadRequest download request}.
53+
*/
54+
public FakeDownloader(DownloadRequest request) {
55+
this.request = request;
56+
downloadStarted = createRobolectricConditionVariable();
57+
removeStarted = createRobolectricConditionVariable();
58+
finished = createRobolectricConditionVariable();
59+
blocker = createRobolectricConditionVariable();
60+
startCount = new AtomicInteger();
61+
bytesDownloaded = new AtomicInteger();
62+
}
63+
64+
@Override
65+
public void cancel() {
66+
canceled = true;
67+
blocker.open();
68+
}
69+
70+
@Override
71+
public void download(@Nullable ProgressListener progressListener) throws IOException {
72+
startCount.incrementAndGet();
73+
downloadStarted.open();
74+
try {
75+
block();
76+
if (canceled) {
77+
return;
78+
}
79+
int bytesDownloaded = this.bytesDownloaded.get();
80+
if (progressListener != null && bytesDownloaded > 0) {
81+
progressListener.onProgress(C.LENGTH_UNSET, bytesDownloaded, C.PERCENTAGE_UNSET);
82+
}
83+
if (enableDownloadIoException) {
84+
enableDownloadIoException = false;
85+
throw new IOException();
86+
}
87+
} finally {
88+
finished.open();
89+
}
90+
}
91+
92+
@Override
93+
public void remove() {
94+
startCount.incrementAndGet();
95+
removeStarted.open();
96+
try {
97+
block();
98+
} finally {
99+
finished.open();
100+
}
101+
}
102+
103+
/** Finishes the {@link #download} or {@link #remove} without an error. */
104+
public void finish() throws InterruptedException {
105+
blocker.open();
106+
blockUntilFinished();
107+
}
108+
109+
/** Fails {@link #download} or {@link #remove} with an error. */
110+
public void fail() throws InterruptedException {
111+
enableDownloadIoException = true;
112+
blocker.open();
113+
blockUntilFinished();
114+
}
115+
116+
/** Increments the number of bytes that the fake downloader has downloaded. */
117+
public void incrementBytesDownloaded() {
118+
bytesDownloaded.incrementAndGet();
119+
}
120+
121+
/** Asserts that the {@link FakeDownloader} instance was created with the given {@code id}. */
122+
public void assertId(String id) {
123+
assertThat(request.id).isEqualTo(id);
124+
}
125+
126+
/**
127+
* Asserts that the {@link FakeDownloader} instance was created with the given {@code streamKeys}.
128+
*/
129+
public void assertStreamKeys(StreamKey... streamKeys) {
130+
assertThat(request.streamKeys).containsExactlyElementsIn(streamKeys);
131+
}
132+
133+
/** Asserts that {@link #download} has started. */
134+
public void assertDownloadStarted() throws InterruptedException {
135+
assertThat(downloadStarted.block(TIMEOUT_MS)).isTrue();
136+
downloadStarted.close();
137+
}
138+
139+
/** Asserts that {@link #remove} has started. */
140+
public void assertRemoveStarted() throws InterruptedException {
141+
assertThat(removeStarted.block(TIMEOUT_MS)).isTrue();
142+
removeStarted.close();
143+
}
144+
145+
/** Asserts that {@link #download} or {@link #remove} has been cancelled. */
146+
public void assertCanceled() throws InterruptedException {
147+
blockUntilFinished();
148+
assertThat(canceled).isTrue();
149+
}
150+
151+
// Internal methods.
152+
153+
private void block() {
154+
try {
155+
blocker.block();
156+
} catch (InterruptedException e) {
157+
throw new IllegalStateException(e); // Never happens.
158+
} finally {
159+
blocker.close();
160+
}
161+
}
162+
163+
private void blockUntilFinished() throws InterruptedException {
164+
assertThat(finished.block(TIMEOUT_MS)).isTrue();
165+
finished.close();
166+
}
167+
}

0 commit comments

Comments
 (0)