From c16bbdfc9691b663cf11c6269fef296e6d189a8f Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Tue, 7 May 2019 14:58:34 +0200 Subject: [PATCH 1/2] Do not block when using Sonic+Sleep timer --- .../core/service/playback/LocalPSMP.java | 2 +- .../playback/PlaybackServiceTaskManager.java | 25 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) 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 28889cee3..d0ad45f1c 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 @@ -1106,7 +1106,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { if (useCallerThread) { r.run(); } else { - new Thread(r).start(); + executor.submit(r); } } } 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 730ae7734..624ecdf90 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 @@ -16,6 +16,7 @@ import java.util.concurrent.TimeUnit; 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 de.greenrobot.event.EventBus; @@ -320,7 +321,7 @@ public class PlaybackServiceTaskManager { private final boolean shakeToReset; private final boolean vibrate; private ShakeListener shakeListener; - private Handler handler; + private final Handler handler; public SleepTimer(long waitingTime, boolean shakeToReset, boolean vibrate) { super(); @@ -328,7 +329,21 @@ public class PlaybackServiceTaskManager { this.timeLeft = waitingTime; this.shakeToReset = shakeToReset; this.vibrate = vibrate; - this.handler = new Handler(); // Use the same thread for callbacks (ExoPlayer) + + if (UserPreferences.useExoplayer() && Looper.myLooper() == Looper.getMainLooper()) { + // Run callbacks in main thread so they can call ExoPlayer methods themselves + this.handler = new Handler(); + } else { + this.handler = null; + } + } + + private void postCallback(Runnable r) { + if (handler == null) { + r.run(); + } else { + handler.post(r); + } } @Override @@ -354,7 +369,7 @@ public class PlaybackServiceTaskManager { if(shakeListener == null && shakeToReset) { shakeListener = new ShakeListener(context, this); } - handler.post(callback::onSleepTimerAlmostExpired); + postCallback(callback::onSleepTimerAlmostExpired); notifiedAlmostExpired = true; } if (timeLeft <= 0) { @@ -364,7 +379,7 @@ public class PlaybackServiceTaskManager { shakeListener = null; } if (!Thread.currentThread().isInterrupted()) { - handler.post(callback::onSleepTimerExpired); + postCallback(callback::onSleepTimerExpired); } else { Log.d(TAG, "Sleep timer interrupted"); } @@ -382,7 +397,7 @@ public class PlaybackServiceTaskManager { } public void onShake() { - handler.post(() -> { + postCallback(() -> { setSleepTimer(waitingTime, shakeToReset, vibrate); callback.onSleepTimerReset(); }); From 5a9958098564a38513ace68aac92c235aab3d65e Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Tue, 7 May 2019 15:21:54 +0200 Subject: [PATCH 2/2] Do not deadlock on seek when using Sonic Callbacks are called on the thread that created the MediaPlayer. For Sonic, this is the executor. For ExoPlayer, this is the main thread. When calling executor.submit, every thread waiting for the runnable to complete gets blocked. Because the callback is called in the thread that created the player, we can simply remove the call to executor.submit and still be sure that a background thread is used. --- .../core/service/playback/LocalPSMP.java | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) 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 d0ad45f1c..a4099bf94 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 @@ -1088,25 +1088,17 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { mp -> genericSeekCompleteListener(); private void genericSeekCompleteListener() { - Runnable r = () -> { - Log.d(TAG, "genericSeekCompleteListener"); - if(seekLatch != null) { - seekLatch.countDown(); - } - playerLock.lock(); - if (playerStatus == PlayerStatus.PLAYING) { - callback.onPlaybackStart(media, getPosition()); - } - if (playerStatus == PlayerStatus.SEEKING) { - setPlayerStatus(statusBeforeSeeking, media, getPosition()); - } - playerLock.unlock(); - }; - - if (useCallerThread) { - r.run(); - } else { - executor.submit(r); + Log.d(TAG, "genericSeekCompleteListener"); + if (seekLatch != null) { + seekLatch.countDown(); } + playerLock.lock(); + if (playerStatus == PlayerStatus.PLAYING) { + callback.onPlaybackStart(media, getPosition()); + } + if (playerStatus == PlayerStatus.SEEKING) { + setPlayerStatus(statusBeforeSeeking, media, getPosition()); + } + playerLock.unlock(); } }