From d40b9ef59b422ad6ccf0e31245e9a28757e39fc1 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 18 Mar 2024 07:28:17 +0100 Subject: [PATCH] Decouple media button starter and receiver (#6999) --- .../antennapod/playback/PlaybackTest.java | 6 ++--- .../antennapod/activity/MainActivity.java | 4 ++-- .../actionbutton/PauseActionButton.java | 4 ++-- .../fragment/AudioPlayerFragment.java | 4 ++-- .../menuhandler/FeedItemMenuHandler.java | 4 ++-- .../core/receiver/MediaButtonReceiver.java | 15 ------------ .../service/QuickSettingsTileService.java | 8 ++----- .../antennapod/core/widget/WidgetUpdater.java | 14 +++++------ .../ui/appstartintent/MediaButtonStarter.java | 24 +++++++++++++++++++ 9 files changed, 44 insertions(+), 39 deletions(-) create mode 100644 ui/app-start-intent/src/main/java/de/danoeh/antennapod/ui/appstartintent/MediaButtonStarter.java diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java index 16605d202..2dc69717c 100644 --- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java @@ -12,7 +12,6 @@ import androidx.test.rule.ActivityTestRule; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.LongList; @@ -23,6 +22,7 @@ import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.model.feed.SortOrder; import de.danoeh.antennapod.playback.base.PlayerStatus; import de.danoeh.antennapod.storage.preferences.UserPreferences; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; import de.test.antennapod.EspressoTestUtils; import de.test.antennapod.IgnoreOnCi; import de.test.antennapod.ui.UITestUtils; @@ -224,11 +224,11 @@ public class PlaybackTest { } private void skipEpisode() { - context.sendBroadcast(MediaButtonReceiver.createIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); + context.sendBroadcast(MediaButtonStarter.createIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); } protected void pauseEpisode() { - context.sendBroadcast(MediaButtonReceiver.createIntent(context, KeyEvent.KEYCODE_MEDIA_PAUSE)); + context.sendBroadcast(MediaButtonStarter.createIntent(context, KeyEvent.KEYCODE_MEDIA_PAUSE)); } protected void startLocalPlayback() { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index 48131f8da..fe1db360b 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -35,8 +35,8 @@ import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; import de.danoeh.antennapod.ui.common.ThemeSwitcher; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.sync.queue.SynchronizationQueueSink; import de.danoeh.antennapod.core.util.download.FeedUpdateManager; import de.danoeh.antennapod.dialog.RatingDialog; @@ -750,7 +750,7 @@ public class MainActivity extends CastEnabledActivity { } if (customKeyCode != null) { - sendBroadcast(MediaButtonReceiver.createIntent(this, customKeyCode)); + sendBroadcast(MediaButtonStarter.createIntent(this, customKeyCode)); return true; } return super.onKeyUp(keyCode, event); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java index 90025d9a2..58cda7bcc 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java @@ -5,10 +5,10 @@ import android.view.KeyEvent; import androidx.annotation.DrawableRes; import androidx.annotation.StringRes; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.util.PlaybackStatus; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; public class PauseActionButton extends ItemActionButton { @@ -36,7 +36,7 @@ public class PauseActionButton extends ItemActionButton { } if (PlaybackStatus.isCurrentlyPlaying(media)) { - context.sendBroadcast(MediaButtonReceiver.createIntent(context, KeyEvent.KEYCODE_MEDIA_PAUSE)); + context.sendBroadcast(MediaButtonStarter.createIntent(context, KeyEvent.KEYCODE_MEDIA_PAUSE)); } } } 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 082bded55..0289e3fc2 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -25,6 +25,7 @@ import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.elevation.SurfaceColors; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -36,7 +37,6 @@ import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.ui.common.Converter; import de.danoeh.antennapod.core.util.TimeSpeedConverter; @@ -211,7 +211,7 @@ public class AudioPlayerFragment extends Fragment implements return false; }); butSkip.setOnClickListener(v -> getActivity().sendBroadcast( - MediaButtonReceiver.createIntent(getContext(), KeyEvent.KEYCODE_MEDIA_NEXT))); + MediaButtonStarter.createIntent(getContext(), KeyEvent.KEYCODE_MEDIA_NEXT))); } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java index a72b32497..5e86e14f0 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java @@ -18,7 +18,6 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.util.FeedUtil; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.service.playback.PlaybackServiceInterface; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.sync.SynchronizationSettings; @@ -31,6 +30,7 @@ import de.danoeh.antennapod.dialog.ShareDialog; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.net.sync.model.EpisodeAction; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; import de.danoeh.antennapod.view.LocalDeleteModal; /** @@ -150,7 +150,7 @@ public class FeedItemMenuHandler { @NonNull Context context = fragment.requireContext(); if (menuItemId == R.id.skip_episode_item) { - context.sendBroadcast(MediaButtonReceiver.createIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); + context.sendBroadcast(MediaButtonStarter.createIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); } else if (menuItemId == R.id.remove_item) { LocalDeleteModal.showLocalFeedDeleteWarningIfNecessary(context, Arrays.asList(selectedItem), () -> DBWriter.deleteFeedMediaOfItem(context, selectedItem.getMedia().getId())); diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java index 837cb692e..8721ebb35 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java @@ -1,10 +1,8 @@ package de.danoeh.antennapod.core.receiver; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.Build; import androidx.core.content.ContextCompat; import android.util.Log; import android.view.KeyEvent; @@ -22,7 +20,6 @@ public class MediaButtonReceiver extends BroadcastReceiver { public static final String EXTRA_SOURCE = "de.danoeh.antennapod.core.service.extra.MediaButtonReceiver.SOURCE"; public static final String EXTRA_HARDWAREBUTTON = "de.danoeh.antennapod.core.service.extra.MediaButtonReceiver.HARDWAREBUTTON"; - public static final String NOTIFY_BUTTON_RECEIVER = "de.danoeh.antennapod.NOTIFY_BUTTON_RECEIVER"; public static final String PLAYBACK_SERVICE_INTENT = "de.danoeh.antennapod.intents.PLAYBACK_SERVICE"; @Override @@ -47,16 +44,4 @@ public class MediaButtonReceiver extends BroadcastReceiver { } } - public static Intent createIntent(Context context, int eventCode) { - KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, eventCode); - Intent startingIntent = new Intent(context, MediaButtonReceiver.class); - startingIntent.setAction(MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); - startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); - return startingIntent; - } - - public static PendingIntent createPendingIntent(Context context, int eventCode) { - return PendingIntent.getBroadcast(context, eventCode, createIntent(context, eventCode), - (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); - } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/QuickSettingsTileService.java b/core/src/main/java/de/danoeh/antennapod/core/service/QuickSettingsTileService.java index ba0b3617e..ee593aa06 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/QuickSettingsTileService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/QuickSettingsTileService.java @@ -12,8 +12,8 @@ import android.view.KeyEvent; import androidx.annotation.RequiresApi; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.service.playback.PlaybackService; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; @RequiresApi(api = Build.VERSION_CODES.N) public class QuickSettingsTileService extends TileService { @@ -29,11 +29,7 @@ public class QuickSettingsTileService extends TileService { @Override public void onClick() { super.onClick(); - Intent intent = new Intent(this, MediaButtonReceiver.class); - intent.setAction(MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); - intent.putExtra(Intent.EXTRA_KEY_EVENT, - new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); - sendBroadcast(intent); + sendBroadcast(MediaButtonStarter.createIntent(this, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); } // Update the tile status when TileService.requestListeningState() is called elsewhere diff --git a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java index bc1cf8a5e..23995d7fe 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java +++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java @@ -17,13 +17,13 @@ import com.bumptech.glide.load.resource.bitmap.FitCenter; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; +import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter; import de.danoeh.antennapod.ui.common.Converter; import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.storage.preferences.UserPreferences; import de.danoeh.antennapod.model.playback.MediaType; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.receiver.PlayerWidget; import de.danoeh.antennapod.core.feed.util.ImageResourceUtils; import de.danoeh.antennapod.core.util.TimeSpeedConverter; @@ -137,21 +137,21 @@ public abstract class WidgetUpdater { views.setContentDescription(R.id.butPlayExtended, context.getString(R.string.play_label)); } views.setOnClickPendingIntent(R.id.butPlay, - MediaButtonReceiver.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + MediaButtonStarter.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); views.setOnClickPendingIntent(R.id.butPlayExtended, - MediaButtonReceiver.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + MediaButtonStarter.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); views.setOnClickPendingIntent(R.id.butRew, - MediaButtonReceiver.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_REWIND)); + MediaButtonStarter.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_REWIND)); views.setOnClickPendingIntent(R.id.butFastForward, - MediaButtonReceiver.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD)); + MediaButtonStarter.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD)); views.setOnClickPendingIntent(R.id.butSkip, - MediaButtonReceiver.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); + MediaButtonStarter.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT)); } else { // start the app if they click anything views.setOnClickPendingIntent(R.id.layout_left, startMediaPlayer); views.setOnClickPendingIntent(R.id.butPlay, startMediaPlayer); views.setOnClickPendingIntent(R.id.butPlayExtended, - MediaButtonReceiver.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + MediaButtonStarter.createPendingIntent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); views.setViewVisibility(R.id.txtvProgress, View.GONE); views.setViewVisibility(R.id.txtvTitle, View.GONE); views.setViewVisibility(R.id.txtNoPlaying, View.VISIBLE); diff --git a/ui/app-start-intent/src/main/java/de/danoeh/antennapod/ui/appstartintent/MediaButtonStarter.java b/ui/app-start-intent/src/main/java/de/danoeh/antennapod/ui/appstartintent/MediaButtonStarter.java new file mode 100644 index 000000000..1c2053a56 --- /dev/null +++ b/ui/app-start-intent/src/main/java/de/danoeh/antennapod/ui/appstartintent/MediaButtonStarter.java @@ -0,0 +1,24 @@ +package de.danoeh.antennapod.ui.appstartintent; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.view.KeyEvent; + +public abstract class MediaButtonStarter { + private static final String INTENT = "de.danoeh.antennapod.NOTIFY_BUTTON_RECEIVER"; + + public static Intent createIntent(Context context, int eventCode) { + KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, eventCode); + Intent startingIntent = new Intent(INTENT); + startingIntent.setPackage(context.getPackageName()); + startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); + return startingIntent; + } + + public static PendingIntent createPendingIntent(Context context, int eventCode) { + return PendingIntent.getBroadcast(context, eventCode, createIntent(context, eventCode), + (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); + } +}