Don't create Downloads until DownloadManager is initialized

PiperOrigin-RevId: 225824428
This commit is contained in:
eguven 2018-12-17 15:41:04 +00:00 committed by Oliver Woodman
parent f4fd3b12e6
commit 3d6707e2c4
6 changed files with 36 additions and 14 deletions

View File

@ -38,7 +38,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -93,6 +92,7 @@ public final class DownloadManager {
private final HandlerThread fileIOThread;
private final Handler fileIOHandler;
private final CopyOnWriteArraySet<Listener> listeners;
private final ArrayDeque<DownloadAction> actionQueue;
private boolean initialized;
private boolean released;
@ -142,6 +142,7 @@ public final class DownloadManager {
fileIOHandler = new Handler(fileIOThread.getLooper());
listeners = new CopyOnWriteArraySet<>();
actionQueue = new ArrayDeque<>();
loadActions();
logd("Created");
@ -194,8 +195,8 @@ public final class DownloadManager {
*/
public void handleAction(DownloadAction action) {
Assertions.checkState(!released);
Download download = getDownloadForAction(action);
if (initialized) {
Download download = getOrAddDownloadForAction(action);
saveActions();
maybeStartDownloads();
if (download.state == STATE_QUEUED) {
@ -204,6 +205,8 @@ public final class DownloadManager {
// reported to listeners. Do so now.
notifyListenersDownloadStateChange(download);
}
} else {
actionQueue.add(action);
}
}
@ -281,7 +284,7 @@ public final class DownloadManager {
logd("Released");
}
private Download getDownloadForAction(DownloadAction action) {
private Download getOrAddDownloadForAction(DownloadAction action) {
for (int i = 0; i < downloads.size(); i++) {
Download download = downloads.get(i);
if (download.action.isSameMedia(action)) {
@ -380,18 +383,18 @@ public final class DownloadManager {
if (released) {
return;
}
List<Download> pendingDownloads = new ArrayList<>(downloads);
downloads.clear();
for (DownloadAction action : actions) {
getDownloadForAction(action);
getOrAddDownloadForAction(action);
}
logd("Downloads are created.");
initialized = true;
for (Listener listener : listeners) {
listener.onInitialized(DownloadManager.this);
}
if (!pendingDownloads.isEmpty()) {
downloads.addAll(pendingDownloads);
if (!actionQueue.isEmpty()) {
while (!actionQueue.isEmpty()) {
getOrAddDownloadForAction(actionQueue.remove());
}
saveActions();
}
maybeStartDownloads();

View File

@ -426,9 +426,9 @@ public class DownloadManagerTest {
actionFile, downloaderFactory, maxActiveDownloadTasks, MIN_RETRY_COUNT);
downloadManagerListener =
new TestDownloadManagerListener(downloadManager, dummyMainThread);
downloadManager.addListener(downloadManagerListener);
downloadManager.startDownloads();
});
downloadManagerListener.waitUntilInitialized();
} catch (Throwable throwable) {
throw new Exception(throwable);
}

View File

@ -247,7 +247,6 @@ public class DownloadManagerDashTest {
downloadManagerListener =
new TestDownloadManagerListener(downloadManager, dummyMainThread);
downloadManager.addListener(downloadManagerListener);
downloadManager.startDownloads();
});
}

View File

@ -124,7 +124,6 @@ public class DownloadServiceDashTest {
/* minRetryCount= */ 3);
downloadManagerListener =
new TestDownloadManagerListener(dashDownloadManager, dummyMainThread);
dashDownloadManager.addListener(downloadManagerListener);
dashDownloadManager.startDownloads();
dashDownloadService =

View File

@ -21,6 +21,8 @@ import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import com.google.android.exoplayer2.util.Util;
import java.util.concurrent.atomic.AtomicReference;
/** Helper class to simulate main/UI thread in tests. */
public final class DummyMainThread {
@ -58,13 +60,21 @@ public final class DummyMainThread {
if (Looper.myLooper() == handler.getLooper()) {
runnable.run();
} else {
final ConditionVariable finishedCondition = new ConditionVariable();
ConditionVariable finishedCondition = new ConditionVariable();
AtomicReference<Throwable> thrown = new AtomicReference<>();
handler.post(
() -> {
try {
runnable.run();
} catch (Throwable t) {
thrown.set(t);
}
finishedCondition.open();
});
assertThat(finishedCondition.block(timeoutMs)).isTrue();
if (thrown.get() != null) {
Util.sneakyThrow(thrown.get());
}
}
}

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.testutil;
import static com.google.common.truth.Truth.assertThat;
import android.os.ConditionVariable;
import com.google.android.exoplayer2.offline.DownloadManager;
import com.google.android.exoplayer2.offline.DownloadManager.DownloadState;
import java.util.HashMap;
@ -28,10 +29,12 @@ import java.util.concurrent.TimeUnit;
public final class TestDownloadManagerListener implements DownloadManager.Listener {
private static final int TIMEOUT = 1000;
private static final int INITIALIZATION_TIMEOUT = 10000;
private final DownloadManager downloadManager;
private final DummyMainThread dummyMainThread;
private final HashMap<String, ArrayBlockingQueue<Integer>> actionStates;
private final ConditionVariable initializedCondition;
private CountDownLatch downloadFinishedCondition;
@DownloadState.FailureReason private int failureReason;
@ -41,6 +44,8 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
this.downloadManager = downloadManager;
this.dummyMainThread = dummyMainThread;
actionStates = new HashMap<>();
initializedCondition = new ConditionVariable();
downloadManager.addListener(this);
}
public Integer pollStateChange(String taskId, long timeoutMs) throws InterruptedException {
@ -53,7 +58,13 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
@Override
public void onInitialized(DownloadManager downloadManager) {
// Do nothing.
initializedCondition.open();
}
public void waitUntilInitialized() {
if (!downloadManager.isInitialized()) {
assertThat(initializedCondition.block(INITIALIZATION_TIMEOUT)).isTrue();
}
}
@Override