diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java index 4078ae4f41..ad7097b762 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java @@ -707,6 +707,7 @@ public final class DownloadManager { private int maxParallelDownloads; private int minRetryCount; private int activeDownloadTaskCount; + private boolean hasActiveRemoveTask; public InternalHandler( HandlerThread thread, @@ -1058,6 +1059,10 @@ public final class DownloadManager { return; } + if (hasActiveRemoveTask) { + return; + } + // We can start a remove task. Downloader downloader = downloaderFactory.createDownloader(download.request); activeTask = @@ -1069,6 +1074,7 @@ public final class DownloadManager { minRetryCount, /* internalHandler= */ this); activeTasks.put(download.request.id, activeTask); + hasActiveRemoveTask = true; activeTask.start(); } @@ -1098,7 +1104,9 @@ public final class DownloadManager { activeTasks.remove(downloadId); boolean isRemove = task.isRemove; - if (!isRemove && --activeDownloadTaskCount == 0) { + if (isRemove) { + hasActiveRemoveTask = false; + } else if (--activeDownloadTaskCount == 0) { removeMessages(MSG_UPDATE_PROGRESS); } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java index b32e627ca7..ed0b26b1e1 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java @@ -283,14 +283,14 @@ public class DownloadManagerTest { postRemoveAllRequest(); // Both downloads should be removed. FakeDownloader downloader2 = getDownloaderAt(2); - FakeDownloader downloader3 = getDownloaderAt(3); downloader2.assertId(ID1); - downloader3.assertId(ID2); downloader2.assertRemoveStarted(); - downloader3.assertRemoveStarted(); downloader2.finish(); - downloader3.finish(); assertRemoved(ID1); + FakeDownloader downloader3 = getDownloaderAt(3); + downloader3.assertId(ID2); + downloader3.assertRemoveStarted(); + downloader3.finish(); assertRemoved(ID2); downloadManagerListener.blockUntilIdleAndThrowAnyFailure(); @@ -712,6 +712,36 @@ public class DownloadManagerTest { assertEqualIgnoringUpdateTime(mergedDownload, expectedDownload); } + @Test + public void removeRequests_runSequentially() throws Throwable { + // Trigger two remove requests. + postDownloadRequest(ID1); + getDownloaderAt(0).finish(); + postDownloadRequest(ID2); + getDownloaderAt(1).finish(); + postRemoveRequest(ID1); + postRemoveRequest(ID2); + + // Assert first remove request is executing, second one is queued. + assertRemoving(ID1); + assertQueued(ID2); + FakeDownloader downloader2 = getDownloaderAt(2); + downloader2.assertId(ID1); + downloader2.assertRemoveStarted(); + downloader2.finish(); + assertRemoved(ID1); + + // Assert second one is running after first one finished + assertRemoving(ID2); + FakeDownloader downloader3 = getDownloaderAt(3); + downloader3.assertId(ID2); + downloader3.assertRemoveStarted(); + downloader3.finish(); + assertRemoved(ID2); + + downloadManagerListener.blockUntilIdleAndThrowAnyFailure(); + } + private void setupDownloadManager(int maxParallelDownloads) throws Exception { if (downloadManager != null) { releaseDownloadManager();