Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ default void onWaitingForRequirementsChanged(
private static final int MSG_RELEASE = 12;

private static final String TAG = "DownloadManager";
private static final int MAX_REMOVE_TASK_COUNT = 1;

private final Context context;
private final WritableDownloadIndex downloadIndex;
Expand Down Expand Up @@ -709,6 +710,7 @@ private static final class InternalHandler extends Handler {
private int maxParallelDownloads;
private int minRetryCount;
private int activeDownloadTaskCount;
private int activeRemoveTaskCount;

public InternalHandler(
HandlerThread thread,
Expand Down Expand Up @@ -1060,6 +1062,10 @@ private void syncRemovingDownload(@Nullable Task activeTask, Download download)
return;
}

if (activeRemoveTaskCount >= MAX_REMOVE_TASK_COUNT) {
return;
}

// We can start a remove task.
Downloader downloader = downloaderFactory.createDownloader(download.request);
activeTask =
Expand All @@ -1071,6 +1077,7 @@ private void syncRemovingDownload(@Nullable Task activeTask, Download download)
minRetryCount,
/* internalHandler= */ this);
activeTasks.put(download.request.id, activeTask);
activeRemoveTaskCount++;
activeTask.start();
}

Expand Down Expand Up @@ -1100,7 +1107,9 @@ private void onTaskStopped(Task task) {
activeTasks.remove(downloadId);

boolean isRemove = task.isRemove;
if (!isRemove && --activeDownloadTaskCount == 0) {
if (isRemove) {
activeRemoveTaskCount--;
} else if (--activeDownloadTaskCount == 0) {
removeMessages(MSG_UPDATE_PROGRESS);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,61 @@ public void mergeRequest_completedWithStopReason_becomesStopped() {
assertEqualIgnoringUpdateTime(mergedDownload, expectedDownload);
}

@Test
public void remove_tasks_run_sequentially()
throws Throwable {
DefaultDownloadIndex defaultDownloadIndex =
new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider());
defaultDownloadIndex.putDownload(
new Download(
new DownloadRequest.Builder(ID1, Uri.EMPTY).build(),
Download.STATE_REMOVING,
0,
1,
2,
Download.STOP_REASON_NONE,
Download.FAILURE_REASON_NONE
)
);
defaultDownloadIndex.putDownload(
new Download(
new DownloadRequest.Builder(ID2, Uri.EMPTY).build(),
Download.STATE_RESTARTING,
0,
1,
2,
Download.STOP_REASON_NONE,
Download.FAILURE_REASON_NONE
)
);
setupDownloadManager(100, defaultDownloadIndex);

// The second removal should wait and the first one should be able to complete.
FakeDownloader downloader0 = getDownloaderAt(0);
assertNoDownloaderAt(1);
downloader0.assertId(ID1);
downloader0.assertRemoveStarted();
downloader0.finish();
assertRemoved(ID1);

// The second removal can start once the first one has completed, and removes a download with
// state STATE_RESTARTING, so it should result in a new download being queued.
FakeDownloader downloader1 = getDownloaderAt(1);
downloader1.assertId(ID2);
downloader1.assertRemoveStarted();
downloader1.finish();
assertQueued(ID2);
}

private void setupDownloadManager(int maxParallelDownloads) throws Exception {
setupDownloadManager(
maxParallelDownloads, new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider())
);
}

private void setupDownloadManager(
int maxParallelDownloads, WritableDownloadIndex writableDownloadIndex
) throws Exception {
if (downloadManager != null) {
releaseDownloadManager();
}
Expand All @@ -723,7 +777,7 @@ private void setupDownloadManager(int maxParallelDownloads) throws Exception {
downloadManager =
new DownloadManager(
ApplicationProvider.getApplicationContext(),
new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider()),
writableDownloadIndex,
new FakeDownloaderFactory());
downloadManager.setMaxParallelDownloads(maxParallelDownloads);
downloadManager.setMinRetryCount(MIN_RETRY_COUNT);
Expand Down