bugfix: Ensure playback service use the updated feedItem after media download completes (rather than trying to stream)

This commit is contained in:
orionlee 2019-09-29 12:46:21 -07:00
parent 1709877531
commit 9469ebc6c3
2 changed files with 78 additions and 6 deletions

View File

@ -5,6 +5,11 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.LargeTest;
import org.greenrobot.eventbus.EventBus;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -15,14 +20,15 @@ import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.service.playback.PlaybackServiceTaskManager;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.playback.Playable;
import org.greenrobot.eventbus.EventBus;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@ -123,6 +129,42 @@ public class PlaybackServiceTaskManagerTest {
pstm.shutdown();
}
@Test
public void testQueueUpdatedUponDownloadComplete() throws Exception {
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();
{ // Setup test data
List<FeedItem> queue = writeTestQueue("a");
FeedItem item = DBReader.getFeedItem(queue.get(0).getId());
FeedMedia media = new FeedMedia(item, "http://abc.test/acme.mp3", 12345, "audio/mp3");
item.setMedia(media);
DBWriter.setFeedMedia(media).get();
DBWriter.setFeedItem(item).get();
}
PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM);
final FeedItem testItem = pstm.getQueue().get(0);
assertThat("The item is not yet downloaded",
testItem.getMedia().isDownloaded(), is(false));
{ // simulate download complete (in DownloadService.MediaHandlerThread)
FeedItem item = DBReader.getFeedItem(testItem.getId());
item.getMedia().setDownloaded(true);
item.getMedia().setFile_url("file://123");
item.setAutoDownload(false);
DBWriter.setFeedItem(item).get();
DBWriter.setFeedMedia(item.getMedia()).get();
}
// an approximation to ensure the item update event has been posted and processed.
Thread.sleep(10);
final FeedItem itemUpdated = pstm.getQueue().get(0);
assertThat("The queue in PlaybackService has been updated item after download is completed",
itemUpdated.getMedia().isDownloaded(), is(true));
pstm.shutdown();
}
@Test
public void testStartPositionSaver() throws InterruptedException {
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();

View File

@ -7,6 +7,9 @@ import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.util.Log;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -14,13 +17,12 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.playback.Playable;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -102,6 +104,34 @@ public class PlaybackServiceTaskManager {
}
}
@Subscribe
public void onEvent(FeedItemEvent event) {
// Use case: when an item in the queue has been downloaded,
// listening to the event to ensure the downloaded item will be used.
Log.d(TAG, "onEvent(FeedItemEvent " + event + ")");
for (FeedItem item : event.items) {
if (isItemInQueue(item.getId())) {
Log.d(TAG, "onEvent(FeedItemEvent) - some item (" + item.getId() + ") in the queue has been updated (usually downloaded). Refresh the queue.");
cancelQueueLoader();
loadQueue();
return;
}
}
}
private boolean isItemInQueue(long itemId) {
List<FeedItem> queue = getQueueIfLoaded();
if (queue != null) {
for (FeedItem item : queue) {
if (item.getId() == itemId) {
return true;
}
}
}
return false;
}
/**
* Returns the queue if it is already loaded or null if it hasn't been loaded yet.
* In order to wait until the queue has been loaded, use getQueue()