From 97905e5ed4afc273e6e4165682aa820e50ac05da Mon Sep 17 00:00:00 2001 From: orionlee Date: Wed, 23 May 2018 15:37:03 -0700 Subject: #2448: make podcast episode enqueue position respect download start order --- .../download/handler/MediaDownloadedHandler.java | 13 +++---- .../de/danoeh/antennapod/core/storage/DBTasks.java | 4 +++ .../danoeh/antennapod/core/storage/DBWriter.java | 40 ++++++++++++++++++++-- .../antennapod/core/storage/DownloadRequester.java | 2 +- .../FeedFileDownloadStatusRequesterInterface.java | 13 +++++++ 5 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/storage/FeedFileDownloadStatusRequesterInterface.java (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java index cf5a84eea..7465b5b38 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java @@ -3,22 +3,22 @@ package de.danoeh.antennapod.core.service.download.handler; import android.content.Context; import android.media.MediaMetadataRetriever; import android.util.Log; + import androidx.annotation.NonNull; + +import java.util.concurrent.ExecutionException; + import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.DownloadError; -import java.util.concurrent.ExecutionException; - /** * Handles a completed media download. */ @@ -82,11 +82,6 @@ public class MediaDownloadedHandler implements Runnable { // to ensure subscribers will get the updated FeedMedia as well DBWriter.setFeedItem(item).get(); } - - if (item != null && UserPreferences.enqueueDownloadedEpisodes() - && !DBTasks.isInQueue(context, item.getId())) { - DBWriter.addQueueItem(context, item).get(); - } } catch (InterruptedException e) { Log.e(TAG, "MediaHandlerThread was interrupted"); } catch (ExecutionException e) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java index 9d37a5f2a..def4d84b5 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java @@ -329,6 +329,10 @@ public final class DBTasks { }.start(); } + // #2448: First, add to-download items to the queue before actual download + // so that the resulting queue order is the same as when download is clicked + DBWriter.addQueueItem(context, items); + // Then, download them for (FeedItem item : items) { if (item.getMedia() != null && !requester.isDownloadingFile(item.getMedia()) diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index 097f07b27..1ba58f3d3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -330,7 +330,7 @@ public class DBWriter { new ItemEnqueuePositionCalculator.Options() .setEnqueueAtFront(UserPreferences.enqueueAtFront()) .setKeepInProgressAtFront(UserPreferences.keepInProgressAtFront()) - ); + ); for (int i = 0; i < itemIds.length; i++) { if (!itemListContains(queue, itemIds[i])) { @@ -426,6 +426,12 @@ public class DBWriter { private final @NonNull Options options; + /** + * The logic needs to use {@link DownloadRequester#isDownloadingFile(FeedFile)} method only + */ + @VisibleForTesting + FeedFileDownloadStatusRequesterInterface requester = DownloadRequester.getInstance(); + public ItemEnqueuePositionCalculator(@NonNull Options options) { this.options = options; } @@ -447,16 +453,44 @@ public class DBWriter { curQueue.size() > 0 && curQueue.get(0).getMedia() != null && curQueue.get(0).getMedia().isInProgress()) { - return positionAmongToAdd + 1; // leave the front in progress item at the front + // leave the front in progress item at the front + return getPositionOf1stNonDownloadingItem(positionAmongToAdd + 1, curQueue); } else { // typical case // return NOT 0, so that when a list of items are inserted, the items inserted // keep the same order. Returning 0 will reverse the order - return positionAmongToAdd; + return getPositionOf1stNonDownloadingItem(positionAmongToAdd, curQueue); } } else { return curQueue.size(); } } + + private int getPositionOf1stNonDownloadingItem(int startPosition, List curQueue) { + final int curQueueSize = curQueue.size(); + for (int i = startPosition; i < curQueueSize; i++) { + if (!isItemAtPositionDownloading(i, curQueue)) { + return i; + } // else continue to search; + } + return curQueueSize; + } + + private boolean isItemAtPositionDownloading(int position, List curQueue) { + FeedItem curItem; + try { + curItem = curQueue.get(position); + } catch (IndexOutOfBoundsException e) { + curItem = null; + } + + if (curItem != null && + curItem.getMedia() != null && + requester.isDownloadingFile(curItem.getMedia())) { + return true; + } else { + return false; + } + } } /** diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index 71f6845c5..8d4a197ad 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -31,7 +31,7 @@ import de.danoeh.antennapod.core.util.URLChecker; * Sends download requests to the DownloadService. This class should always be used for starting downloads, * otherwise they won't work correctly. */ -public class DownloadRequester { +public class DownloadRequester implements FeedFileDownloadStatusRequesterInterface { private static final String TAG = "DownloadRequester"; private static final String FEED_DOWNLOADPATH = "cache/"; diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedFileDownloadStatusRequesterInterface.java b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedFileDownloadStatusRequesterInterface.java new file mode 100644 index 000000000..c33b5c137 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedFileDownloadStatusRequesterInterface.java @@ -0,0 +1,13 @@ +package de.danoeh.antennapod.core.storage; + +import android.support.annotation.NonNull; + +import de.danoeh.antennapod.core.feed.FeedFile; + +public interface FeedFileDownloadStatusRequesterInterface { + /** + * @return {@code true} if the named feedfile is in the downloads list + */ + boolean isDownloadingFile(@NonNull FeedFile item); + +} -- cgit v1.2.3