summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorTony Tam <149837+tonytamsf@users.noreply.github.com>2024-03-17 00:52:16 -1000
committerGitHub <noreply@github.com>2024-03-17 11:52:16 +0100
commit8dc8cc64a8a6de3adfba1aaf0a0306f90727a2c4 (patch)
tree6edcb4ae7600a7f6353684b418833257fbe746f2 /core
parent48c0ccb4a261eed51959973e86e673ec27462bfa (diff)
downloadAntennaPod-8dc8cc64a8a6de3adfba1aaf0a0306f90727a2c4.zip
Allow retrying chapter loading if interrupted (#6828)
Chapter loading can sometimes get interrupted, most importantly if the corresponding fragment tries to refresh the view again. Before, this set the chapters to an empty list, indicating that it should not be tried again. Now, interrupted exceptions do not set the list to be empty, so it can be retried later.
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java17
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java66
2 files changed, 51 insertions, 32 deletions
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 98c470f21..55831b821 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
@@ -10,6 +10,7 @@ import de.danoeh.antennapod.model.MediaMetadataRetrieverCompat;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
+import java.io.InterruptedIOException;
import java.util.concurrent.ExecutionException;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
@@ -54,14 +55,18 @@ public class MediaDownloadedHandler implements Runnable {
media.setSize(new File(request.getDestination()).length());
media.checkEmbeddedPicture(); // enforce check
- // check if file has chapters
- if (media.getItem() != null && !media.getItem().hasChapters()) {
- media.setChapters(ChapterUtils.loadChaptersFromMediaFile(media, context));
+ try {
+ // Cache chapters if file has them
+ if (media.getItem() != null && !media.getItem().hasChapters()) {
+ media.setChapters(ChapterUtils.loadChaptersFromMediaFile(media, context));
+ }
+ if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) {
+ ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl(), false);
+ }
+ } catch (InterruptedIOException ignore) {
+ // Ignore
}
- if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) {
- ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl(), false);
- }
// Get duration
String durationStr = null;
try (MediaMetadataRetrieverCompat mmr = new MediaMetadataRetrieverCompat()) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
index 084b34e76..901771913 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
@@ -28,6 +28,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.util.Collections;
import java.util.List;
@@ -60,42 +61,50 @@ public class ChapterUtils {
return;
}
- List<Chapter> chaptersFromDatabase = null;
- List<Chapter> chaptersFromPodcastIndex = null;
- if (playable instanceof FeedMedia) {
- FeedMedia feedMedia = (FeedMedia) playable;
- if (feedMedia.getItem() == null) {
- feedMedia.setItem(DBReader.getFeedItem(feedMedia.getItemId()));
- }
- if (feedMedia.getItem().hasChapters()) {
- chaptersFromDatabase = DBReader.loadChaptersOfFeedItem(feedMedia.getItem());
- }
+ try {
+ List<Chapter> chaptersFromDatabase = null;
+ List<Chapter> chaptersFromPodcastIndex = null;
+ if (playable instanceof FeedMedia) {
+ FeedMedia feedMedia = (FeedMedia) playable;
+ if (feedMedia.getItem() == null) {
+ feedMedia.setItem(DBReader.getFeedItem(feedMedia.getItemId()));
+ }
+ if (feedMedia.getItem().hasChapters()) {
+ chaptersFromDatabase = DBReader.loadChaptersOfFeedItem(feedMedia.getItem());
+ }
+
+ if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) {
+ chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl(
+ feedMedia.getItem().getPodcastIndexChapterUrl(), forceRefresh);
+ }
- if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) {
- chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl(
- feedMedia.getItem().getPodcastIndexChapterUrl(), forceRefresh);
}
- }
-
- List<Chapter> chaptersFromMediaFile = ChapterUtils.loadChaptersFromMediaFile(playable, context);
- List<Chapter> chaptersMergePhase1 = ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile);
- List<Chapter> chapters = ChapterMerger.merge(chaptersMergePhase1, chaptersFromPodcastIndex);
- if (chapters == null) {
- // Do not try loading again. There are no chapters.
- playable.setChapters(Collections.emptyList());
- } else {
- playable.setChapters(chapters);
+ List<Chapter> chaptersFromMediaFile = ChapterUtils.loadChaptersFromMediaFile(playable, context);
+ List<Chapter> chaptersMergePhase1 = ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile);
+ List<Chapter> chapters = ChapterMerger.merge(chaptersMergePhase1, chaptersFromPodcastIndex);
+ if (chapters == null) {
+ // Do not try loading again. There are no chapters or parsing failed.
+ playable.setChapters(Collections.emptyList());
+ } else {
+ playable.setChapters(chapters);
+ }
+ } catch (InterruptedIOException e) {
+ Log.d(TAG, "Chapter loading interrupted");
+ playable.setChapters(null); // Allow later retry
}
}
- public static List<Chapter> loadChaptersFromMediaFile(Playable playable, Context context) {
+ public static List<Chapter> loadChaptersFromMediaFile(Playable playable, Context context)
+ throws InterruptedIOException {
try (CountingInputStream in = openStream(playable, context)) {
List<Chapter> chapters = readId3ChaptersFrom(in);
if (!chapters.isEmpty()) {
Log.i(TAG, "Chapters loaded");
return chapters;
}
+ } catch (InterruptedIOException e) {
+ throw e;
} catch (IOException | ID3ReaderException e) {
Log.e(TAG, "Unable to load ID3 chapters: " + e.getMessage());
}
@@ -106,6 +115,8 @@ public class ChapterUtils {
Log.i(TAG, "Chapters loaded");
return chapters;
}
+ } catch (InterruptedIOException e) {
+ throw e;
} catch (IOException | VorbisCommentReaderException e) {
Log.e(TAG, "Unable to load vorbis chapters: " + e.getMessage());
}
@@ -135,7 +146,7 @@ public class ChapterUtils {
}
}
- public static List<Chapter> loadChaptersFromUrl(String url, boolean forceRefresh) {
+ public static List<Chapter> loadChaptersFromUrl(String url, boolean forceRefresh) throws InterruptedIOException {
if (forceRefresh) {
return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK);
}
@@ -147,7 +158,8 @@ public class ChapterUtils {
return cachedChapters;
}
- private static List<Chapter> loadChaptersFromUrl(String url, CacheControl cacheControl) {
+ private static List<Chapter> loadChaptersFromUrl(String url, CacheControl cacheControl)
+ throws InterruptedIOException {
Response response = null;
try {
Request request = new Request.Builder().url(url).cacheControl(cacheControl).build();
@@ -155,6 +167,8 @@ public class ChapterUtils {
if (response.isSuccessful() && response.body() != null) {
return PodcastIndexChapterParser.parse(response.body().string());
}
+ } catch (InterruptedIOException e) {
+ throw e;
} catch (IOException e) {
e.printStackTrace();
} finally {