diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/CancelablePSMPCallback.java b/app/src/androidTest/java/de/test/antennapod/service/playback/CancelablePSMPCallback.java index 30a84ecb9..2c164f131 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/CancelablePSMPCallback.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/CancelablePSMPCallback.java @@ -34,22 +34,6 @@ public class CancelablePSMPCallback implements PlaybackServiceMediaPlayer.PSMPCa originalCallback.shouldStop(); } - @Override - public void playbackSpeedChanged(float s) { - if (isCancelled) { - return; - } - originalCallback.playbackSpeedChanged(s); - } - - @Override - public void onBufferingUpdate(int percent) { - if (isCancelled) { - return; - } - originalCallback.onBufferingUpdate(percent); - } - @Override public void onMediaChanged(boolean reloadUI) { if (isCancelled) { diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/DefaultPSMPCallback.java b/app/src/androidTest/java/de/test/antennapod/service/playback/DefaultPSMPCallback.java index 167b1b55c..090a94d6e 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/DefaultPSMPCallback.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/DefaultPSMPCallback.java @@ -17,16 +17,6 @@ public class DefaultPSMPCallback implements PlaybackServiceMediaPlayer.PSMPCallb } - @Override - public void playbackSpeedChanged(float s) { - - } - - @Override - public void onBufferingUpdate(int percent) { - - } - @Override public void onMediaChanged(boolean reloadUI) { diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java index 7803144e1..5dd419412 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java @@ -5,10 +5,12 @@ import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.LargeTest; +import de.danoeh.antennapod.core.event.playback.SleepTimerUpdatedEvent; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.widget.WidgetUpdater; 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; @@ -172,21 +174,6 @@ public class PlaybackServiceTaskManagerTest { countDownLatch.countDown(); } - @Override - public void onSleepTimerAlmostExpired(long timeLeft) { - - } - - @Override - public void onSleepTimerExpired() { - - } - - @Override - public void onSleepTimerReset() { - - } - @Override public WidgetUpdater.WidgetState requestWidgetState() { return null; @@ -233,21 +220,6 @@ public class PlaybackServiceTaskManagerTest { } - @Override - public void onSleepTimerAlmostExpired(long timeLeft) { - - } - - @Override - public void onSleepTimerExpired() { - - } - - @Override - public void onSleepTimerReset() { - - } - @Override public WidgetUpdater.WidgetState requestWidgetState() { countDownLatch.countDown(); @@ -325,42 +297,20 @@ public class PlaybackServiceTaskManagerTest { final long TIME = 2000; final long TIMEOUT = 2 * TIME; final CountDownLatch countDownLatch = new CountDownLatch(1); - PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, new PlaybackServiceTaskManager.PSTMCallback() { - @Override - public void positionSaverTick() { - - } - - @Override - public void onSleepTimerAlmostExpired(long timeLeft) { - - } - - @Override - public void onSleepTimerExpired() { + Object timerReceiver = new Object() { + @Subscribe + public void sleepTimerUpdate(SleepTimerUpdatedEvent event) { if (countDownLatch.getCount() == 0) { fail(); } countDownLatch.countDown(); } - - @Override - public void onSleepTimerReset() { - - } - - @Override - public WidgetUpdater.WidgetState requestWidgetState() { - return null; - } - - @Override - public void onChapterLoaded(Playable media) { - - } - }); + }; + EventBus.getDefault().register(timerReceiver); + PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM); pstm.setSleepTimer(TIME); countDownLatch.await(TIMEOUT, TimeUnit.MILLISECONDS); + EventBus.getDefault().unregister(timerReceiver); pstm.shutdown(); } @@ -368,44 +318,26 @@ public class PlaybackServiceTaskManagerTest { @UiThreadTest public void testDisableSleepTimer() throws InterruptedException { final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext(); - final long TIME = 1000; + final long TIME = 5000; final long TIMEOUT = 2 * TIME; final CountDownLatch countDownLatch = new CountDownLatch(1); - PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, new PlaybackServiceTaskManager.PSTMCallback() { - @Override - public void positionSaverTick() { - + Object timerReceiver = new Object() { + @Subscribe + public void sleepTimerUpdate(SleepTimerUpdatedEvent event) { + if (event.isOver()) { + countDownLatch.countDown(); + } else if (event.getTimeLeft() == 1) { + fail("Arrived at 1 but should have been cancelled"); + } } - - @Override - public void onSleepTimerAlmostExpired(long timeLeft) { - - } - - @Override - public void onSleepTimerExpired() { - fail("Sleeptimer expired"); - } - - @Override - public void onSleepTimerReset() { - - } - - @Override - public WidgetUpdater.WidgetState requestWidgetState() { - return null; - } - - @Override - public void onChapterLoaded(Playable media) { - - } - }); + }; + PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM); + EventBus.getDefault().register(timerReceiver); pstm.setSleepTimer(TIME); pstm.disableSleepTimer(); assertFalse(countDownLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)); pstm.shutdown(); + EventBus.getDefault().unregister(timerReceiver); } @Test @@ -435,21 +367,6 @@ public class PlaybackServiceTaskManagerTest { } - @Override - public void onSleepTimerAlmostExpired(long timeLeft) { - - } - - @Override - public void onSleepTimerExpired() { - - } - - @Override - public void onSleepTimerReset() { - - } - @Override public WidgetUpdater.WidgetState requestWidgetState() { return null; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index c35709f05..5d7ab8959 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -36,9 +36,11 @@ import androidx.core.view.WindowCompat; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import com.bumptech.glide.Glide; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerErrorEvent; -import de.danoeh.antennapod.core.event.ServiceEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackServiceEvent; +import de.danoeh.antennapod.core.event.playback.SleepTimerUpdatedEvent; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; @@ -192,31 +194,11 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. VideoplayerActivity.this.onPositionObserverUpdate(); } - @Override - public void onBufferStart() { - viewBinding.progressBar.setVisibility(View.VISIBLE); - } - - @Override - public void onBufferEnd() { - viewBinding.progressBar.setVisibility(View.INVISIBLE); - } - - @Override - public void onBufferUpdate(float progress) { - viewBinding.sbPosition.setSecondaryProgress((int) (progress * viewBinding.sbPosition.getMax())); - } - @Override public void onReloadNotification(int code) { VideoplayerActivity.this.onReloadNotification(code); } - @Override - public void onSleepTimerUpdate() { - supportInvalidateOptionsMenu(); - } - @Override protected void updatePlayButtonShowsPlay(boolean showPlay) { viewBinding.playButton.setIsShowPlay(showPlay); @@ -252,6 +234,26 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. }; } + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void bufferUpdate(BufferUpdateEvent event) { + if (event.hasStarted()) { + viewBinding.progressBar.setVisibility(View.VISIBLE); + } else if (event.hasEnded()) { + viewBinding.progressBar.setVisibility(View.INVISIBLE); + } else { + viewBinding.sbPosition.setSecondaryProgress((int) (event.getProgress() * viewBinding.sbPosition.getMax())); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void sleepTimerUpdate(SleepTimerUpdatedEvent event) { + if (event.isCancelled() || event.wasJustEnabled()) { + supportInvalidateOptionsMenu(); + } + } + protected void loadMediaInfo() { Log.d(TAG, "loadMediaInfo()"); if (controller == null || controller.getMedia() == null) { @@ -535,8 +537,8 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. } @Subscribe(threadMode = ThreadMode.MAIN) - public void onPlaybackServiceChanged(ServiceEvent event) { - if (event.action == ServiceEvent.Action.SERVICE_SHUT_DOWN) { + public void onPlaybackServiceChanged(PlaybackServiceEvent event) { + if (event.action == PlaybackServiceEvent.Action.SERVICE_SHUT_DOWN) { finish(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java index 31c2d3369..f4b3b1bfa 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java @@ -12,9 +12,13 @@ import android.widget.Button; import android.widget.CheckBox; import android.widget.TextView; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.event.playback.SpeedChangedEvent; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.view.PlaybackSpeedSeekBar; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import java.util.List; import java.util.Locale; @@ -44,16 +48,12 @@ public class PlaybackControlsDialog extends DialogFragment { public void loadMediaInfo() { setupUi(); setupAudioTracks(); - updateSpeed(); - } - - @Override - public void onPlaybackSpeedChange() { - updateSpeed(); + updateSpeed(new SpeedChangedEvent(getCurrentPlaybackSpeedMultiplier())); } }; controller.init(); setupUi(); + EventBus.getDefault().register(this); } @Override @@ -61,6 +61,7 @@ public class PlaybackControlsDialog extends DialogFragment { super.onStop(); controller.release(); controller = null; + EventBus.getDefault().unregister(this); } @NonNull @@ -79,10 +80,9 @@ public class PlaybackControlsDialog extends DialogFragment { speedSeekBar.setProgressChangedListener(speed -> { if (controller != null) { controller.setPlaybackSpeed(speed); - updateSpeed(); } }); - updateSpeed(); + updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier())); final CheckBox stereoToMono = dialog.findViewById(R.id.stereo_to_mono); stereoToMono.setChecked(UserPreferences.stereoToMono()); @@ -111,12 +111,10 @@ public class PlaybackControlsDialog extends DialogFragment { }); } - private void updateSpeed() { - if (controller != null) { - txtvPlaybackSpeed.setText(String.format( - Locale.getDefault(), "%.2fx", controller.getCurrentPlaybackSpeedMultiplier())); - speedSeekBar.updateSpeed(controller.getCurrentPlaybackSpeedMultiplier()); - } + @Subscribe(threadMode = ThreadMode.MAIN) + public void updateSpeed(SpeedChangedEvent event) { + txtvPlaybackSpeed.setText(String.format(Locale.getDefault(), "%.2fx", event.getNewSpeed())); + speedSeekBar.updateSpeed(event.getNewSpeed()); } private void setupAudioTracks() { diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java index 691bd65e8..26e222539 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java @@ -18,20 +18,17 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.event.playback.SleepTimerUpdatedEvent; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.playback.PlaybackController; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; - -import java.util.concurrent.TimeUnit; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; public class SleepTimerDialog extends DialogFragment { private PlaybackController controller; - private Disposable timeUpdater; - private EditText etxtTime; private Spinner spTimeUnit; private LinearLayout timeSetup; @@ -46,20 +43,12 @@ public class SleepTimerDialog extends DialogFragment { public void onStart() { super.onStart(); controller = new PlaybackController(getActivity()) { - @Override - public void onSleepTimerUpdate() { - updateTime(); - } - @Override public void loadMediaInfo() { - updateTime(); } }; controller.init(); - timeUpdater = Observable.interval(1, TimeUnit.SECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(tick -> updateTime()); + EventBus.getDefault().register(this); } @Override @@ -68,9 +57,7 @@ public class SleepTimerDialog extends DialogFragment { if (controller != null) { controller.release(); } - if (timeUpdater != null) { - timeUpdater.dispose(); - } + EventBus.getDefault().unregister(this); } @NonNull @@ -170,13 +157,12 @@ public class SleepTimerDialog extends DialogFragment { return builder.create(); } - private void updateTime() { - if (controller == null) { - return; - } - timeSetup.setVisibility(controller.sleepTimerActive() ? View.GONE : View.VISIBLE); - timeDisplay.setVisibility(controller.sleepTimerActive() ? View.VISIBLE : View.GONE); - time.setText(Converter.getDurationStringLong((int) controller.getSleepTimerTimeLeft())); + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void timerUpdated(SleepTimerUpdatedEvent event) { + timeDisplay.setVisibility(event.isOver() || event.isCancelled() ? View.GONE : View.VISIBLE); + timeSetup.setVisibility(event.isOver() || event.isCancelled() ? View.VISIBLE : View.GONE); + time.setText(Converter.getDurationStringLong((int) event.getTimeLeft())); } private void closeKeyboard(View content) { diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java index 5d13f6f00..12cb26409 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java @@ -15,10 +15,14 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.chip.Chip; import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.event.playback.SpeedChangedEvent; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.view.ItemOffsetDecoration; import de.danoeh.antennapod.view.PlaybackSpeedSeekBar; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -46,23 +50,13 @@ public class VariableSpeedDialog extends BottomSheetDialogFragment { public void onStart() { super.onStart(); controller = new PlaybackController(getActivity()) { - @Override - public void onPlaybackSpeedChange() { - updateSpeed(); - } - @Override public void loadMediaInfo() { - updateSpeed(); + updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier())); } }; controller.init(); - updateSpeed(); - } - - private void updateSpeed() { - speedSeekBar.updateSpeed(controller.getCurrentPlaybackSpeedMultiplier()); - addCurrentSpeedChip.setText(speedFormat.format(controller.getCurrentPlaybackSpeedMultiplier())); + EventBus.getDefault().register(this); } @Override @@ -70,6 +64,13 @@ public class VariableSpeedDialog extends BottomSheetDialogFragment { super.onStop(); controller.release(); controller = null; + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void updateSpeed(SpeedChangedEvent event) { + speedSeekBar.updateSpeed(event.getNewSpeed()); + addCurrentSpeedChip.setText(speedFormat.format(event.getNewSpeed())); } @Nullable diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index eef2c0fff..77c99c3a8 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -25,7 +25,11 @@ import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.snackbar.Snackbar; +import de.danoeh.antennapod.core.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackServiceEvent; import de.danoeh.antennapod.core.event.PlayerErrorEvent; +import de.danoeh.antennapod.core.event.playback.SleepTimerUpdatedEvent; +import de.danoeh.antennapod.core.event.playback.SpeedChangedEvent; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -38,8 +42,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.CastEnabledActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.event.FavoritesEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; -import de.danoeh.antennapod.core.event.ServiceEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.model.feed.Chapter; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.model.feed.FeedItem; @@ -224,8 +227,8 @@ public class AudioPlayerFragment extends Fragment implements } @Subscribe(threadMode = ThreadMode.MAIN) - public void onPlaybackServiceChanged(ServiceEvent event) { - if (event.action == ServiceEvent.Action.SERVICE_SHUT_DOWN) { + public void onPlaybackServiceChanged(PlaybackServiceEvent event) { + if (event.action == PlaybackServiceEvent.Action.SERVICE_SHUT_DOWN) { ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); } } @@ -243,14 +246,11 @@ public class AudioPlayerFragment extends Fragment implements }); } - protected void updatePlaybackSpeedButton(Playable media) { - if (butPlaybackSpeed == null || controller == null) { - return; - } - float speed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(media); - String speedStr = new DecimalFormat("0.00").format(speed); + @Subscribe(threadMode = ThreadMode.MAIN) + public void updatePlaybackSpeedButton(SpeedChangedEvent event) { + String speedStr = new DecimalFormat("0.00").format(event.getNewSpeed()); txtvPlaybackSpeed.setText(speedStr); - butPlaybackSpeed.setSpeed(speed); + butPlaybackSpeed.setSpeed(event.getNewSpeed()); } private void loadMediaInfo(boolean includingChapters) { @@ -281,30 +281,6 @@ public class AudioPlayerFragment extends Fragment implements private PlaybackController newPlaybackController() { return new PlaybackController(getActivity()) { - @Override - public void onBufferStart() { - progressIndicator.setVisibility(View.VISIBLE); - } - - @Override - public void onBufferEnd() { - progressIndicator.setVisibility(View.GONE); - } - - @Override - public void onBufferUpdate(float progress) { - if (isStreaming()) { - sbPosition.setSecondaryProgress((int) (progress * sbPosition.getMax())); - } else { - sbPosition.setSecondaryProgress(0); - } - } - - @Override - public void onSleepTimerUpdate() { - AudioPlayerFragment.this.loadMediaInfo(false); - } - @Override protected void updatePlayButtonShowsPlay(boolean showPlay) { butPlay.setIsShowPlay(showPlay); @@ -319,11 +295,6 @@ public class AudioPlayerFragment extends Fragment implements public void onPlaybackEnd() { ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); } - - @Override - public void onPlaybackSpeedChange() { - updatePlaybackSpeedButton(getMedia()); - } }; } @@ -333,11 +304,19 @@ public class AudioPlayerFragment extends Fragment implements } duration = controller.getDuration(); updatePosition(new PlaybackPositionEvent(controller.getPosition(), duration)); - updatePlaybackSpeedButton(media); + updatePlaybackSpeedButton(new SpeedChangedEvent(PlaybackSpeedUtils.getCurrentPlaybackSpeed(media))); setChapterDividers(media); setupOptionsMenu(media); } + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void sleepTimerUpdate(SleepTimerUpdatedEvent event) { + if (event.isCancelled() || event.wasJustEnabled()) { + AudioPlayerFragment.this.loadMediaInfo(false); + } + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -367,6 +346,20 @@ public class AudioPlayerFragment extends Fragment implements } } + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void bufferUpdate(BufferUpdateEvent event) { + if (event.hasStarted()) { + progressIndicator.setVisibility(View.VISIBLE); + } else if (event.hasEnded()) { + progressIndicator.setVisibility(View.GONE); + } else if (controller != null && controller.isStreaming()) { + sbPosition.setSecondaryProgress((int) (event.getProgress() * sbPosition.getMax())); + } else { + sbPosition.setSecondaryProgress(0); + } + } + @Subscribe(threadMode = ThreadMode.MAIN) public void updatePosition(PlaybackPositionEvent event) { if (controller == null || txtvPosition == null || txtvLength == null || sbPosition == null) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java index de14f220e..d323edcb9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java @@ -23,7 +23,7 @@ import org.greenrobot.eventbus.ThreadMode; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.ChaptersListAdapter; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.playback.PlaybackController; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java index 6c8baef29..a65539a14 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -24,7 +24,7 @@ import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloadLogEvent; import de.danoeh.antennapod.core.event.FeedItemEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java index 8c2203f72..397d6a223 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java @@ -45,7 +45,7 @@ import org.greenrobot.eventbus.ThreadMode; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.core.feed.util.ImageResourceUtils; import de.danoeh.antennapod.core.glide.ApGlideSettings; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java index 7ea76bb8d..8abef8685 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -22,7 +22,7 @@ import android.widget.Toast; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index 4e6ba692b..e86694f68 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -17,8 +17,8 @@ import com.bumptech.glide.request.RequestOptions; import com.google.android.material.bottomsheet.BottomSheetBehavior; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; -import de.danoeh.antennapod.core.event.ServiceEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackServiceEvent; import de.danoeh.antennapod.model.playback.MediaType; import de.danoeh.antennapod.core.feed.util.ImageResourceUtils; import de.danoeh.antennapod.core.glide.ApGlideSettings; @@ -147,8 +147,8 @@ public class ExternalPlayerFragment extends Fragment { } @Subscribe(threadMode = ThreadMode.MAIN) - public void onPlaybackServiceChanged(ServiceEvent event) { - if (event.action == ServiceEvent.Action.SERVICE_SHUT_DOWN) { + public void onPlaybackServiceChanged(PlaybackServiceEvent event) { + if (event.action == PlaybackServiceEvent.Action.SERVICE_SHUT_DOWN) { ((MainActivity) getActivity()).setPlayerVisible(false); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java index 0ee60866d..920ae1108 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -55,7 +55,7 @@ import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.FavoritesEvent; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index 5e3d36c03..7fb0b8c44 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -17,8 +17,8 @@ import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.FeedItemEvent; -import de.danoeh.antennapod.core.event.PlaybackHistoryEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackHistoryEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.model.feed.FeedItem; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 1b7d236c6..13a093be3 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -34,7 +34,7 @@ import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.FeedItemEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java index 26c024e1d..837abc838 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -30,7 +30,7 @@ import de.danoeh.antennapod.adapter.FeedSearchResultAdapter; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.FeedItemEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.model.feed.Feed; diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java index cd3af5003..fbd2ae5df 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java +++ b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java @@ -21,7 +21,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.CoverLoader; import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.util.DateFormatter; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/playback/BufferUpdateEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/playback/BufferUpdateEvent.java new file mode 100644 index 000000000..87369c360 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/event/playback/BufferUpdateEvent.java @@ -0,0 +1,35 @@ +package de.danoeh.antennapod.core.event.playback; + +public class BufferUpdateEvent { + private static final float PROGRESS_STARTED = -1; + private static final float PROGRESS_ENDED = -2; + final float progress; + + private BufferUpdateEvent(float progress) { + this.progress = progress; + } + + public static BufferUpdateEvent started() { + return new BufferUpdateEvent(PROGRESS_STARTED); + } + + public static BufferUpdateEvent ended() { + return new BufferUpdateEvent(PROGRESS_ENDED); + } + + public static BufferUpdateEvent progressUpdate(float progress) { + return new BufferUpdateEvent(progress); + } + + public float getProgress() { + return progress; + } + + public boolean hasStarted() { + return progress == PROGRESS_STARTED; + } + + public boolean hasEnded() { + return progress == PROGRESS_ENDED; + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackHistoryEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackHistoryEvent.java similarity index 84% rename from core/src/main/java/de/danoeh/antennapod/core/event/PlaybackHistoryEvent.java rename to core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackHistoryEvent.java index cd3f27bf5..6e5b66b90 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackHistoryEvent.java +++ b/core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackHistoryEvent.java @@ -1,4 +1,4 @@ -package de.danoeh.antennapod.core.event; +package de.danoeh.antennapod.core.event.playback; public class PlaybackHistoryEvent { diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackPositionEvent.java similarity index 88% rename from core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java rename to core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackPositionEvent.java index 3327d8a02..6f3d505d6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java +++ b/core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackPositionEvent.java @@ -1,4 +1,4 @@ -package de.danoeh.antennapod.core.event; +package de.danoeh.antennapod.core.event.playback; public class PlaybackPositionEvent { private final int position; diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackServiceEvent.java similarity index 53% rename from core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java rename to core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackServiceEvent.java index 2230ee84f..af524ad6c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java +++ b/core/src/main/java/de/danoeh/antennapod/core/event/playback/PlaybackServiceEvent.java @@ -1,6 +1,6 @@ -package de.danoeh.antennapod.core.event; +package de.danoeh.antennapod.core.event.playback; -public class ServiceEvent { +public class PlaybackServiceEvent { public enum Action { SERVICE_STARTED, SERVICE_SHUT_DOWN @@ -8,7 +8,7 @@ public class ServiceEvent { public final Action action; - public ServiceEvent(Action action) { + public PlaybackServiceEvent(Action action) { this.action = action; } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/playback/SleepTimerUpdatedEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/playback/SleepTimerUpdatedEvent.java new file mode 100644 index 000000000..37a073799 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/event/playback/SleepTimerUpdatedEvent.java @@ -0,0 +1,38 @@ +package de.danoeh.antennapod.core.event.playback; + +public class SleepTimerUpdatedEvent { + private static final long CANCELLED = Long.MAX_VALUE; + private final long timeLeft; + + private SleepTimerUpdatedEvent(long timeLeft) { + this.timeLeft = timeLeft; + } + + public static SleepTimerUpdatedEvent justEnabled(long timeLeft) { + return new SleepTimerUpdatedEvent(-timeLeft); + } + + public static SleepTimerUpdatedEvent updated(long timeLeft) { + return new SleepTimerUpdatedEvent(Math.max(0, timeLeft)); + } + + public static SleepTimerUpdatedEvent cancelled() { + return new SleepTimerUpdatedEvent(CANCELLED); + } + + public long getTimeLeft() { + return Math.abs(timeLeft); + } + + public boolean isOver() { + return timeLeft == 0; + } + + public boolean wasJustEnabled() { + return timeLeft < 0; + } + + public boolean isCancelled() { + return timeLeft == CANCELLED; + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/playback/SpeedChangedEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/playback/SpeedChangedEvent.java new file mode 100644 index 000000000..2fd20c7fb --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/event/playback/SpeedChangedEvent.java @@ -0,0 +1,13 @@ +package de.danoeh.antennapod.core.event.playback; + +public class SpeedChangedEvent { + private final float newSpeed; + + public SpeedChangedEvent(float newSpeed) { + this.newSpeed = newSpeed; + } + + public float getNewSpeed() { + return newSpeed; + } +} 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 90b3b6ae2..1556e5a51 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 @@ -15,6 +15,8 @@ import androidx.media.AudioAttributesCompat; import androidx.media.AudioFocusRequestCompat; import androidx.media.AudioManagerCompat; import de.danoeh.antennapod.core.event.PlayerErrorEvent; +import de.danoeh.antennapod.core.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.core.event.playback.SpeedChangedEvent; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.playback.MediaPlayerError; import org.antennapod.audio.MediaPlayer; @@ -616,7 +618,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { private void setSpeedSyncAndSkipSilence(float speed, boolean skipSilence) { playerLock.lock(); Log.d(TAG, "Playback speed was set to " + speed); - callback.playbackSpeedChanged(speed); + EventBus.getDefault().post(new SpeedChangedEvent(speed)); mediaPlayer.setPlaybackParams(speed, skipSilence); playerLock.unlock(); } @@ -1057,14 +1059,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { } private final MediaPlayer.OnBufferingUpdateListener audioBufferingUpdateListener = - (mp, percent) -> genericOnBufferingUpdate(percent); + (mp, percent) -> EventBus.getDefault().post(BufferUpdateEvent.progressUpdate(0.01f * percent)); private final android.media.MediaPlayer.OnBufferingUpdateListener videoBufferingUpdateListener = - (mp, percent) -> genericOnBufferingUpdate(percent); - - private void genericOnBufferingUpdate(int percent) { - callback.onBufferingUpdate(percent); - } + (mp, percent) -> EventBus.getDefault().post(BufferUpdateEvent.progressUpdate(0.01f * percent)); private final MediaPlayer.OnInfoListener audioInfoListener = (mp, what, extra) -> genericInfoListener(what); @@ -1073,7 +1071,16 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { (mp, what, extra) -> genericInfoListener(what); private boolean genericInfoListener(int what) { - return callback.onMediaPlayerInfo(what, 0); + switch (what) { + case android.media.MediaPlayer.MEDIA_INFO_BUFFERING_START: + EventBus.getDefault().post(BufferUpdateEvent.started()); + return true; + case android.media.MediaPlayer.MEDIA_INFO_BUFFERING_END: + EventBus.getDefault().post(BufferUpdateEvent.ended()); + return true; + default: + return callback.onMediaPlayerInfo(what, 0); + } } private final MediaPlayer.OnErrorListener audioErrorListener = diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 49a4fb021..3465d952d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -16,7 +16,6 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Configuration; import android.media.AudioManager; -import android.media.MediaPlayer; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -43,7 +42,10 @@ import androidx.core.app.NotificationManagerCompat; import androidx.media.MediaBrowserServiceCompat; import androidx.preference.PreferenceManager; +import de.danoeh.antennapod.core.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackServiceEvent; import de.danoeh.antennapod.core.event.PlayerErrorEvent; +import de.danoeh.antennapod.core.event.playback.SleepTimerUpdatedEvent; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -55,8 +57,7 @@ import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.MessageEvent; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; -import de.danoeh.antennapod.core.event.ServiceEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.settings.SkipIntroEndingChangedEvent; import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent; import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent; @@ -162,18 +163,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { public static final int EXTRA_CODE_VIDEO = 2; public static final int EXTRA_CODE_CAST = 3; - public static final int NOTIFICATION_TYPE_BUFFER_UPDATE = 2; - /** * Receivers of this intent should update their information about the curently playing media */ public static final int NOTIFICATION_TYPE_RELOAD = 3; - /** - * The state of the sleeptimer changed. - */ - public static final int NOTIFICATION_TYPE_SLEEPTIMER_UPDATE = 4; - public static final int NOTIFICATION_TYPE_BUFFER_START = 5; - public static final int NOTIFICATION_TYPE_BUFFER_END = 6; /** * Set a max number of episodes to load for Android Auto, otherwise there could be performance issues @@ -185,11 +178,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { */ public static final int NOTIFICATION_TYPE_PLAYBACK_END = 7; - /** - * Playback speed has changed - */ - public static final int NOTIFICATION_TYPE_PLAYBACK_SPEED_CHANGE = 8; - /** * Returned by getPositionSafe() or getDurationSafe() if the playbackService * is in an invalid state. @@ -318,7 +306,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { flavorHelper.initializeMediaPlayer(PlaybackService.this); mediaSession.setActive(true); - EventBus.getDefault().post(new ServiceEvent(ServiceEvent.Action.SERVICE_STARTED)); + EventBus.getDefault().post(new PlaybackServiceEvent(PlaybackServiceEvent.Action.SERVICE_STARTED)); } @Override @@ -794,25 +782,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { saveCurrentPosition(true, null, PlaybackServiceMediaPlayer.INVALID_TIME); } - @Override - public void onSleepTimerAlmostExpired(long timeLeft) { - final float[] multiplicators = {0.1f, 0.2f, 0.3f, 0.3f, 0.3f, 0.4f, 0.4f, 0.4f, 0.6f, 0.8f}; - float multiplicator = multiplicators[Math.max(0, (int) timeLeft / 1000)]; - Log.d(TAG, "onSleepTimerAlmostExpired: " + multiplicator); - mediaPlayer.setVolume(multiplicator, multiplicator); - } - @Override - public void onSleepTimerExpired() { - mediaPlayer.pause(true, true); - mediaPlayer.setVolume(1.0f, 1.0f); - sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0); - } - - @Override - public void onSleepTimerReset() { - mediaPlayer.setVolume(1.0f, 1.0f); - } @Override public WidgetUpdater.WidgetState requestWidgetState() { @@ -895,16 +865,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { updateNotificationAndMediaSession(getPlayable()); // Stops foreground if not playing } - @Override - public void playbackSpeedChanged(float s) { - sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_SPEED_CHANGE, 0); - } - - @Override - public void onBufferingUpdate(int percent) { - sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_UPDATE, percent); - } - @Override public void onMediaChanged(boolean reloadUI) { Log.d(TAG, "reloadUI callback reached"); @@ -916,26 +876,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public boolean onMediaPlayerInfo(int code, @StringRes int resourceId) { - switch (code) { - case MediaPlayer.MEDIA_INFO_BUFFERING_START: - sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_START, 0); - return true; - case MediaPlayer.MEDIA_INFO_BUFFERING_END: - sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_END, 0); - - Playable playable = getPlayable(); - if (getPlayable() instanceof FeedMedia - && playable.getDuration() <= 0 && mediaPlayer.getDuration() > 0) { - // Playable is being streamed and does not have a duration specified in the feed - playable.setDuration(mediaPlayer.getDuration()); - DBWriter.setFeedMedia((FeedMedia) playable); - updateNotificationAndMediaSession(playable); - } - - return true; - default: - return flavorHelper.onMediaPlayerInfo(PlaybackService.this, code, resourceId); - } + return flavorHelper.onMediaPlayerInfo(PlaybackService.this, code, resourceId); } @Override @@ -993,6 +934,37 @@ public class PlaybackService extends MediaBrowserServiceCompat { stateManager.stopService(); } + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void bufferUpdate(BufferUpdateEvent event) { + if (event.hasEnded()) { + Playable playable = getPlayable(); + if (getPlayable() instanceof FeedMedia + && playable.getDuration() <= 0 && mediaPlayer.getDuration() > 0) { + // Playable is being streamed and does not have a duration specified in the feed + playable.setDuration(mediaPlayer.getDuration()); + DBWriter.setFeedMedia((FeedMedia) playable); + updateNotificationAndMediaSession(playable); + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + @SuppressWarnings("unused") + public void sleepTimerUpdate(SleepTimerUpdatedEvent event) { + if (event.isOver()) { + mediaPlayer.pause(true, true); + mediaPlayer.setVolume(1.0f, 1.0f); + } else if (event.getTimeLeft() < PlaybackServiceTaskManager.SleepTimer.NOTIFICATION_THRESHOLD) { + final float[] multiplicators = {0.1f, 0.2f, 0.3f, 0.3f, 0.3f, 0.4f, 0.4f, 0.4f, 0.6f, 0.8f}; + float multiplicator = multiplicators[Math.max(0, (int) event.getTimeLeft() / 1000)]; + Log.d(TAG, "onSleepTimerAlmostExpired: " + multiplicator); + mediaPlayer.setVolume(multiplicator, multiplicator); + } else if (event.isCancelled()) { + mediaPlayer.setVolume(1.0f, 1.0f); + } + } + private Playable getNextInQueue(final Playable currentMedia) { if (!(currentMedia instanceof FeedMedia)) { Log.d(TAG, "getNextInQueue(), but playable not an instance of FeedMedia, so not proceeding"); @@ -1158,12 +1130,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { public void setSleepTimer(long waitingTime) { Log.d(TAG, "Setting sleep timer to " + waitingTime + " milliseconds"); taskManager.setSleepTimer(waitingTime); - sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0); } public void disableSleepTimer() { taskManager.disableSleepTimer(); - sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0); } private void sendNotificationBroadcast(int type, int code) { @@ -1578,7 +1548,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void onReceive(Context context, Intent intent) { if (TextUtils.equals(intent.getAction(), ACTION_SHUTDOWN_PLAYBACK_SERVICE)) { - EventBus.getDefault().post(new ServiceEvent(ServiceEvent.Action.SERVICE_SHUT_DOWN)); + EventBus.getDefault().post(new PlaybackServiceEvent(PlaybackServiceEvent.Action.SERVICE_SHUT_DOWN)); stateManager.stopService(); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java index 2aeb84cb0..623ad58bb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java @@ -348,10 +348,6 @@ public abstract class PlaybackServiceMediaPlayer { void shouldStop(); - void playbackSpeedChanged(float s); - - void onBufferingUpdate(int percent); - void onMediaChanged(boolean reloadUI); boolean onMediaPlayerInfo(int code, @StringRes int resourceId); 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 a14605e5b..a99a178da 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 @@ -7,6 +7,7 @@ import android.os.Vibrator; import androidx.annotation.NonNull; import android.util.Log; +import de.danoeh.antennapod.core.event.playback.SleepTimerUpdatedEvent; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.widget.WidgetUpdater; @@ -25,7 +26,6 @@ import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.model.playback.Playable; import io.reactivex.Completable; @@ -244,6 +244,7 @@ public class PlaybackServiceTaskManager { } sleepTimer = new SleepTimer(waitingTime); sleepTimerFuture = schedExecutor.schedule(sleepTimer, 0, TimeUnit.MILLISECONDS); + EventBus.getDefault().post(SleepTimerUpdatedEvent.justEnabled(waitingTime)); } /** @@ -377,27 +378,11 @@ public class PlaybackServiceTaskManager { private final long waitingTime; private long timeLeft; private ShakeListener shakeListener; - private final Handler handler; public SleepTimer(long waitingTime) { super(); this.waitingTime = waitingTime; this.timeLeft = waitingTime; - - if (UserPreferences.useExoplayer() && Looper.myLooper() == Looper.getMainLooper()) { - // Run callbacks in main thread so they can call ExoPlayer methods themselves - this.handler = new Handler(Looper.getMainLooper()); - } else { - this.handler = null; - } - } - - private void postCallback(Runnable r) { - if (handler == null) { - r.run(); - } else { - handler.post(r); - } } @Override @@ -417,6 +402,7 @@ public class PlaybackServiceTaskManager { timeLeft -= now - lastTick; lastTick = now; + EventBus.getDefault().post(SleepTimerUpdatedEvent.updated(timeLeft)); if (timeLeft < NOTIFICATION_THRESHOLD) { Log.d(TAG, "Sleep timer is about to expire"); if (SleepTimerPreferences.vibrate() && !hasVibrated) { @@ -429,7 +415,6 @@ public class PlaybackServiceTaskManager { if (shakeListener == null && SleepTimerPreferences.shakeToReset()) { shakeListener = new ShakeListener(context, this); } - postCallback(() -> callback.onSleepTimerAlmostExpired(timeLeft)); } if (timeLeft <= 0) { Log.d(TAG, "Sleep timer expired"); @@ -438,11 +423,6 @@ public class PlaybackServiceTaskManager { shakeListener = null; } hasVibrated = false; - if (!Thread.currentThread().isInterrupted()) { - postCallback(callback::onSleepTimerExpired); - } else { - Log.d(TAG, "Sleep timer interrupted"); - } } } } @@ -452,10 +432,8 @@ public class PlaybackServiceTaskManager { } public void restart() { - postCallback(() -> { - setSleepTimer(waitingTime); - callback.onSleepTimerReset(); - }); + EventBus.getDefault().post(SleepTimerUpdatedEvent.cancelled()); + setSleepTimer(waitingTime); if (shakeListener != null) { shakeListener.pause(); shakeListener = null; @@ -467,19 +445,13 @@ public class PlaybackServiceTaskManager { if (shakeListener != null) { shakeListener.pause(); } - postCallback(callback::onSleepTimerReset); + EventBus.getDefault().post(SleepTimerUpdatedEvent.cancelled()); } } public interface PSTMCallback { void positionSaverTick(); - void onSleepTimerAlmostExpired(long timeLeft); - - void onSleepTimerExpired(); - - void onSleepTimerReset(); - WidgetUpdater.WidgetState requestWidgetState(); void onChapterLoaded(Playable media); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index 479a7763c..f659fb34d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -27,7 +27,7 @@ import de.danoeh.antennapod.core.event.FavoritesEvent; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; import de.danoeh.antennapod.core.event.MessageEvent; -import de.danoeh.antennapod.core.event.PlaybackHistoryEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackHistoryEvent; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.feed.FeedEvent; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index ec74b2fe3..649e97c42 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -12,7 +12,8 @@ import android.util.Log; import android.util.Pair; import android.view.SurfaceHolder; import androidx.annotation.NonNull; -import de.danoeh.antennapod.core.event.ServiceEvent; +import de.danoeh.antennapod.core.event.playback.PlaybackServiceEvent; +import de.danoeh.antennapod.core.event.playback.SpeedChangedEvent; import de.danoeh.antennapod.model.playback.MediaType; import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; @@ -68,8 +69,8 @@ public abstract class PlaybackController { } @Subscribe(threadMode = ThreadMode.MAIN) - public void onEventMainThread(ServiceEvent event) { - if (event.action == ServiceEvent.Action.SERVICE_STARTED) { + public void onEventMainThread(PlaybackServiceEvent event) { + if (event.action == PlaybackServiceEvent.Action.SERVICE_STARTED) { init(); } } @@ -206,10 +207,6 @@ public abstract class PlaybackController { return; } switch (type) { - case PlaybackService.NOTIFICATION_TYPE_BUFFER_UPDATE: - float progress = ((float) code) / 100; - onBufferUpdate(progress); - break; case PlaybackService.NOTIFICATION_TYPE_RELOAD: if (playbackService == null && PlaybackService.isRunning) { bindToService(); @@ -220,21 +217,9 @@ public abstract class PlaybackController { onReloadNotification(intent.getIntExtra( PlaybackService.EXTRA_NOTIFICATION_CODE, -1)); break; - case PlaybackService.NOTIFICATION_TYPE_SLEEPTIMER_UPDATE: - onSleepTimerUpdate(); - break; - case PlaybackService.NOTIFICATION_TYPE_BUFFER_START: - onBufferStart(); - break; - case PlaybackService.NOTIFICATION_TYPE_BUFFER_END: - onBufferEnd(); - break; case PlaybackService.NOTIFICATION_TYPE_PLAYBACK_END: onPlaybackEnd(); break; - case PlaybackService.NOTIFICATION_TYPE_PLAYBACK_SPEED_CHANGE: - onPlaybackSpeedChange(); - break; } } @@ -242,22 +227,11 @@ public abstract class PlaybackController { public void onPositionObserverUpdate() {} - - public void onPlaybackSpeedChange() {} - /** * Called when the currently displayed information should be refreshed. */ public void onReloadNotification(int code) {} - public void onBufferStart() {} - - public void onBufferEnd() {} - - public void onBufferUpdate(float progress) {} - - public void onSleepTimerUpdate() {} - public void onPlaybackEnd() {} /** @@ -470,7 +444,7 @@ public abstract class PlaybackController { if (playbackService != null) { playbackService.setSpeed(speed); } else { - onPlaybackSpeedChange(); + EventBus.getDefault().post(new SpeedChangedEvent(speed)); } }