From 60968089ae4afe13ba48d64346ea39c542ad457b Mon Sep 17 00:00:00 2001 From: Herbert Reiter <46045854+damoasda@users.noreply.github.com> Date: Sun, 7 Feb 2021 17:57:09 +0100 Subject: Refactoring: Remove ClientConfig.automaticDownloadAlgorithm (#4924) --- .../core/storage/APDownloadAlgorithm.java | 103 --------------------- .../core/storage/AutomaticDownloadAlgorithm.java | 90 +++++++++++++++++- .../de/danoeh/antennapod/core/storage/DBTasks.java | 18 +++- 3 files changed, 101 insertions(+), 110 deletions(-) delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java (limited to 'core/src/main/java/de/danoeh') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java deleted file mode 100644 index 061d6cf3f..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java +++ /dev/null @@ -1,103 +0,0 @@ -package de.danoeh.antennapod.core.storage; - -import android.content.Context; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import de.danoeh.antennapod.core.feed.FeedFilter; -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.feed.FeedPreferences; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.util.NetworkUtils; -import de.danoeh.antennapod.core.util.PowerUtils; - -/** - * Implements the automatic download algorithm used by AntennaPod. This class assumes that - * the client uses the APEpisodeCleanupAlgorithm. - */ -public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm { - private static final String TAG = "APDownloadAlgorithm"; - - /** - * Looks for undownloaded episodes in the queue or list of new items and request a download if - * 1. Network is available - * 2. The device is charging or the user allows auto download on battery - * 3. There is free space in the episode cache - * This method is executed on an internal single thread executor. - * - * @param context Used for accessing the DB. - * @return A Runnable that will be submitted to an ExecutorService. - */ - @Override - public Runnable autoDownloadUndownloadedItems(final Context context) { - return () -> { - - // true if we should auto download based on network status - boolean networkShouldAutoDl = NetworkUtils.autodownloadNetworkAvailable() - && UserPreferences.isEnableAutodownload(); - - // true if we should auto download based on power status - boolean powerShouldAutoDl = PowerUtils.deviceCharging(context) - || UserPreferences.isEnableAutodownloadOnBattery(); - - // we should only auto download if both network AND power are happy - if (networkShouldAutoDl && powerShouldAutoDl) { - - Log.d(TAG, "Performing auto-dl of undownloaded episodes"); - - List candidates; - final List queue = DBReader.getQueue(); - final List newItems = DBReader.getNewItemsList(0, Integer.MAX_VALUE); - candidates = new ArrayList<>(queue.size() + newItems.size()); - candidates.addAll(queue); - for (FeedItem newItem : newItems) { - FeedPreferences feedPrefs = newItem.getFeed().getPreferences(); - FeedFilter feedFilter = feedPrefs.getFilter(); - if (!candidates.contains(newItem) && feedFilter.shouldAutoDownload(newItem)) { - candidates.add(newItem); - } - } - - // filter items that are not auto downloadable - Iterator it = candidates.iterator(); - while (it.hasNext()) { - FeedItem item = it.next(); - if (!item.isAutoDownloadable() || item.getFeed().isLocalFeed()) { - it.remove(); - } - } - - int autoDownloadableEpisodes = candidates.size(); - int downloadedEpisodes = DBReader.getNumberOfDownloadedEpisodes(); - int deletedEpisodes = UserPreferences.getEpisodeCleanupAlgorithm() - .makeRoomForEpisodes(context, autoDownloadableEpisodes); - boolean cacheIsUnlimited = - UserPreferences.getEpisodeCacheSize() == UserPreferences.getEpisodeCacheSizeUnlimited(); - int episodeCacheSize = UserPreferences.getEpisodeCacheSize(); - - int episodeSpaceLeft; - if (cacheIsUnlimited || episodeCacheSize >= downloadedEpisodes + autoDownloadableEpisodes) { - episodeSpaceLeft = autoDownloadableEpisodes; - } else { - episodeSpaceLeft = episodeCacheSize - (downloadedEpisodes - deletedEpisodes); - } - - FeedItem[] itemsToDownload = candidates.subList(0, episodeSpaceLeft) - .toArray(new FeedItem[episodeSpaceLeft]); - - if (itemsToDownload.length > 0) { - Log.d(TAG, "Enqueueing " + itemsToDownload.length + " items for download"); - - try { - DownloadRequester.getInstance().downloadMedia(false, context, false, itemsToDownload); - } catch (DownloadRequestException e) { - e.printStackTrace(); - } - } - } - }; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java index dbb77e19c..f8b643ccf 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java @@ -1,11 +1,28 @@ package de.danoeh.antennapod.core.storage; import android.content.Context; +import android.util.Log; -public interface AutomaticDownloadAlgorithm { +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import de.danoeh.antennapod.core.feed.FeedFilter; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedPreferences; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.NetworkUtils; +import de.danoeh.antennapod.core.util.PowerUtils; + +/** + * Implements the automatic download algorithm used by AntennaPod. This class assumes that + * the client uses the {@link EpisodeCleanupAlgorithm}. + */ +public class AutomaticDownloadAlgorithm { + private static final String TAG = "DownloadAlgorithm"; /** - * Looks for undownloaded episodes and request a download if + * Looks for undownloaded episodes in the queue or list of new items and request a download if * 1. Network is available * 2. The device is charging or the user allows auto download on battery * 3. There is free space in the episode cache @@ -14,5 +31,72 @@ public interface AutomaticDownloadAlgorithm { * @param context Used for accessing the DB. * @return A Runnable that will be submitted to an ExecutorService. */ - Runnable autoDownloadUndownloadedItems(Context context); + public Runnable autoDownloadUndownloadedItems(final Context context) { + return () -> { + + // true if we should auto download based on network status + boolean networkShouldAutoDl = NetworkUtils.autodownloadNetworkAvailable() + && UserPreferences.isEnableAutodownload(); + + // true if we should auto download based on power status + boolean powerShouldAutoDl = PowerUtils.deviceCharging(context) + || UserPreferences.isEnableAutodownloadOnBattery(); + + // we should only auto download if both network AND power are happy + if (networkShouldAutoDl && powerShouldAutoDl) { + + Log.d(TAG, "Performing auto-dl of undownloaded episodes"); + + List candidates; + final List queue = DBReader.getQueue(); + final List newItems = DBReader.getNewItemsList(0, Integer.MAX_VALUE); + candidates = new ArrayList<>(queue.size() + newItems.size()); + candidates.addAll(queue); + for (FeedItem newItem : newItems) { + FeedPreferences feedPrefs = newItem.getFeed().getPreferences(); + FeedFilter feedFilter = feedPrefs.getFilter(); + if (!candidates.contains(newItem) && feedFilter.shouldAutoDownload(newItem)) { + candidates.add(newItem); + } + } + + // filter items that are not auto downloadable + Iterator it = candidates.iterator(); + while (it.hasNext()) { + FeedItem item = it.next(); + if (!item.isAutoDownloadable() || item.getFeed().isLocalFeed()) { + it.remove(); + } + } + + int autoDownloadableEpisodes = candidates.size(); + int downloadedEpisodes = DBReader.getNumberOfDownloadedEpisodes(); + int deletedEpisodes = UserPreferences.getEpisodeCleanupAlgorithm() + .makeRoomForEpisodes(context, autoDownloadableEpisodes); + boolean cacheIsUnlimited = + UserPreferences.getEpisodeCacheSize() == UserPreferences.getEpisodeCacheSizeUnlimited(); + int episodeCacheSize = UserPreferences.getEpisodeCacheSize(); + + int episodeSpaceLeft; + if (cacheIsUnlimited || episodeCacheSize >= downloadedEpisodes + autoDownloadableEpisodes) { + episodeSpaceLeft = autoDownloadableEpisodes; + } else { + episodeSpaceLeft = episodeCacheSize - (downloadedEpisodes - deletedEpisodes); + } + + FeedItem[] itemsToDownload = candidates.subList(0, episodeSpaceLeft) + .toArray(new FeedItem[episodeSpaceLeft]); + + if (itemsToDownload.length > 0) { + Log.d(TAG, "Enqueueing " + itemsToDownload.length + " items for download"); + + try { + DownloadRequester.getInstance().downloadMedia(false, context, false, itemsToDownload); + } catch (DownloadRequestException e) { + e.printStackTrace(); + } + } + } + }; + } } 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 ec39e7144..48a3f574a 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 @@ -6,7 +6,9 @@ import android.database.Cursor; import android.os.Looper; import android.text.TextUtils; import android.util.Log; -import de.danoeh.antennapod.core.ClientConfig; + +import androidx.annotation.VisibleForTesting; + import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; @@ -53,6 +55,8 @@ public final class DBTasks { */ private static final ExecutorService autodownloadExec; + private static AutomaticDownloadAlgorithm downloadAlgorithm = new AutomaticDownloadAlgorithm(); + static { autodownloadExec = Executors.newSingleThreadExecutor(r -> { Thread t = new Thread(r); @@ -278,7 +282,7 @@ public final class DBTasks { } /** - * Looks for undownloaded episodes in the queue or list of unread items and request a download if + * Looks for non-downloaded episodes in the queue or list of unread items and request a download if * 1. Network is available * 2. The device is charging or the user allows auto download on battery * 3. There is free space in the episode cache @@ -289,9 +293,15 @@ public final class DBTasks { */ public static Future autodownloadUndownloadedItems(final Context context) { Log.d(TAG, "autodownloadUndownloadedItems"); - return autodownloadExec.submit(ClientConfig.automaticDownloadAlgorithm - .autoDownloadUndownloadedItems(context)); + return autodownloadExec.submit(downloadAlgorithm.autoDownloadUndownloadedItems(context)); + } + /** + * For testing purpose only. + */ + @VisibleForTesting(otherwise = VisibleForTesting.NONE) + public static void setDownloadAlgorithm(AutomaticDownloadAlgorithm newDownloadAlgorithm) { + downloadAlgorithm = newDownloadAlgorithm; } /** -- cgit v1.2.3