Merge pull request #3471 from orionlee/bugfix2_player_not_using_downloaded_media_2947
New fix player stuck due to streaming rather than using downloaded media
This commit is contained in:
commit
f862d15753
|
@ -5,23 +5,31 @@ import android.support.test.InstrumentationRegistry;
|
|||
import android.support.test.annotation.UiThreadTest;
|
||||
import android.support.test.filters.LargeTest;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
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.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 io.reactivex.functions.Consumer;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
@ -123,6 +131,72 @@ 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://example.com/episode.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);
|
||||
assertFalse("The item should not yet be downloaded", testItem.getMedia().isDownloaded());
|
||||
|
||||
withFeedItemEventListener( feedItemEventListener -> {
|
||||
// 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.setFeedMedia(item.getMedia()).get();
|
||||
DBWriter.setFeedItem(item).get();
|
||||
|
||||
Awaitility.await()
|
||||
.atMost(1000, TimeUnit.MILLISECONDS)
|
||||
.until(() -> feedItemEventListener.getEvents().size() > 0);
|
||||
|
||||
final FeedItem itemUpdated = pstm.getQueue().get(0);
|
||||
assertTrue("media.isDownloaded() should be true - The queue in PlaybackService should be updated after download is completed",
|
||||
itemUpdated.getMedia().isDownloaded());
|
||||
});
|
||||
|
||||
pstm.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an listener subscribing to {@link FeedItemEvent} that the callers can use
|
||||
*
|
||||
* Note: it uses RxJava's version of {@link Consumer} because it allows exceptions to be thrown.
|
||||
*/
|
||||
private static void withFeedItemEventListener(Consumer<FeedItemEventListener> consumer) throws Exception {
|
||||
FeedItemEventListener feedItemEventListener = new FeedItemEventListener();
|
||||
try {
|
||||
EventBus.getDefault().register(feedItemEventListener);
|
||||
consumer.accept(feedItemEventListener);
|
||||
} finally {
|
||||
EventBus.getDefault().unregister(feedItemEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FeedItemEventListener {
|
||||
|
||||
private final List<FeedItemEvent> events = new ArrayList<>();
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(FeedItemEvent event) {
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
List<? extends FeedItemEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartPositionSaver() throws InterruptedException {
|
||||
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
|
|
@ -997,14 +997,17 @@ public class DownloadService extends Service {
|
|||
final FeedItem item = media.getItem();
|
||||
|
||||
try {
|
||||
DBWriter.setFeedMedia(media).get();
|
||||
|
||||
// we've received the media, we don't want to autodownload it again
|
||||
if (item != null) {
|
||||
item.setAutoDownload(false);
|
||||
// setFeedItem() signals (via EventBus) that the item has been updated,
|
||||
// so we do it after the enclosing media has been updated above,
|
||||
// to ensure subscribers will get the updated FeedMedia as well
|
||||
DBWriter.setFeedItem(item).get();
|
||||
}
|
||||
|
||||
DBWriter.setFeedMedia(media).get();
|
||||
|
||||
if (item != null && UserPreferences.enqueueDownloadedEpisodes() &&
|
||||
!DBTasks.isInQueue(DownloadService.this, item.getId())) {
|
||||
DBWriter.addQueueItem(DownloadService.this, item).get();
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue