summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorH. Lehmann <ByteHamster@users.noreply.github.com>2019-04-11 20:50:56 +0200
committerGitHub <noreply@github.com>2019-04-11 20:50:56 +0200
commit97d08f3b00f864d421608ac52e42beafc37e323d (patch)
treea5f2061613f6a1f8fd73128f6d9f157d54abfe9b /core/src/main
parentbe6eb1c738beb7d5671647211d39d15c2edb235e (diff)
parent1d0e22135e57c7bcff8988c388d7f0f813ad7061 (diff)
downloadAntennaPod-97d08f3b00f864d421608ac52e42beafc37e323d.zip
Merge pull request #3097 from ByteHamster/exoplayer-main-thread
Executing all ExoPlayer methods on main thread
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java47
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java19
3 files changed, 60 insertions, 7 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
index 281bd064b..f20525f73 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
@@ -165,6 +165,7 @@ public class ExoPlayerWrapper implements IPlayer {
@Override
public void seekTo(int i) throws IllegalStateException {
mExoPlayer.seekTo(i);
+ audioSeekCompleteListener.onSeekComplete(null);
}
@Override
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
index 9274b9a49..649082f6e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
@@ -18,6 +18,7 @@ import java.io.File;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -57,16 +58,42 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
private final ReentrantLock playerLock;
private CountDownLatch seekLatch;
- private final ThreadPoolExecutor executor;
+ private final PlayerExecutor executor;
+
+ /**
+ * All ExoPlayer methods must be executed on the same thread.
+ * We use the main application thread. This class allows to
+ * "fake" an executor that just calls the methods on the
+ * calling thread instead of submitting to an executor.
+ * Other players are still executed in a background thread.
+ */
+ private class PlayerExecutor {
+ private boolean useCallerThread = true;
+ private ThreadPoolExecutor threadPool;
+
+ public Future<?> submit(Runnable r) {
+ if (useCallerThread) {
+ r.run();
+ return new FutureTask<Void>(() -> {}, null);
+ } else {
+ return threadPool.submit(r);
+ }
+ }
+
+ public void shutdown() {
+ threadPool.shutdown();
+ }
+ }
public LocalPSMP(@NonNull Context context,
@NonNull PSMPCallback callback) {
super(context, callback);
-
this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
this.playerLock = new ReentrantLock();
this.startWhenPrepared = new AtomicBoolean(false);
- executor = new ThreadPoolExecutor(1, 1, 5, TimeUnit.MINUTES, new LinkedBlockingDeque<>(),
+
+ executor = new PlayerExecutor();
+ executor.threadPool = new ThreadPoolExecutor(1, 1, 5, TimeUnit.MINUTES, new LinkedBlockingDeque<>(),
(r, executor) -> Log.d(TAG, "Rejected execution of runnable"));
mediaPlayer = null;
@@ -105,6 +132,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override
public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
Log.d(TAG, "playMediaObject(...)");
+ executor.useCallerThread = UserPreferences.useExoplayer();
executor.submit(() -> {
playerLock.lock();
try {
@@ -372,6 +400,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public void reinit() {
+ executor.useCallerThread = UserPreferences.useExoplayer();
executor.submit(() -> {
playerLock.lock();
Log.d(TAG, "reinit()");
@@ -821,6 +850,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override
protected Future<?> endPlayback(final boolean hasEnded, final boolean wasSkipped,
final boolean shouldContinue, final boolean toStoppedState) {
+ executor.useCallerThread = UserPreferences.useExoplayer();
return executor.submit(() -> {
playerLock.lock();
releaseWifiLockIfNecessary();
@@ -1012,7 +1042,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
mp -> genericSeekCompleteListener();
private void genericSeekCompleteListener() {
- Thread t = new Thread(() -> {
+ Runnable r = () -> {
Log.d(TAG, "genericSeekCompleteListener");
if(seekLatch != null) {
seekLatch.countDown();
@@ -1025,7 +1055,12 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
setPlayerStatus(statusBeforeSeeking, media, getPosition());
}
playerLock.unlock();
- });
- t.start();
+ };
+
+ if (executor.useCallerThread) {
+ r.run();
+ } else {
+ new Thread(r).start();
+ }
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
index 3d97e862a..bfc75a902 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
@@ -1,6 +1,8 @@
package de.danoeh.antennapod.core.service.playback;
import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.util.Log;
@@ -126,6 +128,7 @@ public class PlaybackServiceTaskManager {
public synchronized void startPositionSaver() {
if (!isPositionSaverActive()) {
Runnable positionSaver = callback::positionSaverTick;
+ positionSaver = useMainThreadIfNecessary(positionSaver);
positionSaverFuture = schedExecutor.scheduleWithFixedDelay(positionSaver, POSITION_SAVER_WAITING_INTERVAL,
POSITION_SAVER_WAITING_INTERVAL, TimeUnit.MILLISECONDS);
@@ -158,6 +161,7 @@ public class PlaybackServiceTaskManager {
public synchronized void startWidgetUpdater() {
if (!isWidgetUpdaterActive()) {
Runnable widgetUpdater = callback::onWidgetUpdaterTick;
+ widgetUpdater = useMainThreadIfNecessary(widgetUpdater);
widgetUpdaterFuture = schedExecutor.scheduleWithFixedDelay(widgetUpdater, WIDGET_UPDATER_NOTIFICATION_INTERVAL,
WIDGET_UPDATER_NOTIFICATION_INTERVAL, TimeUnit.MILLISECONDS);
@@ -184,7 +188,8 @@ public class PlaybackServiceTaskManager {
sleepTimerFuture.cancel(true);
}
sleepTimer = new SleepTimer(waitingTime, shakeToReset, vibrate);
- sleepTimerFuture = schedExecutor.schedule(sleepTimer, 0, TimeUnit.MILLISECONDS);
+ Runnable runnable = useMainThreadIfNecessary(sleepTimer);
+ sleepTimerFuture = schedExecutor.schedule(runnable, 0, TimeUnit.MILLISECONDS);
}
/**
@@ -267,6 +272,7 @@ public class PlaybackServiceTaskManager {
}
Log.d(TAG, "Chapter loader stopped");
};
+ chapterLoader = useMainThreadIfNecessary(chapterLoader);
chapterLoaderFuture = schedExecutor.submit(chapterLoader);
}
@@ -292,6 +298,17 @@ public class PlaybackServiceTaskManager {
schedExecutor.shutdown();
}
+ private Runnable useMainThreadIfNecessary(Runnable runnable) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ // Called in main thread => ExoPlayer is used
+ // Run on ui thread even if called from schedExecutor
+ Handler handler = new Handler();
+ return () -> handler.post(runnable);
+ } else {
+ return runnable;
+ }
+ }
+
/**
* Sleeps for a given time and then pauses playback.
*/