summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorByteHamster <ByteHamster@users.noreply.github.com>2021-11-28 22:19:14 +0100
committerGitHub <noreply@github.com>2021-11-28 22:19:14 +0100
commitf0100e61ac633516082ea112363132c99f7c0b7a (patch)
treef7598c0cee85780b409ab895a8041d1607eec312 /app
parentaf2835c59dcb0473aba7a48b38f5abe28dca34d3 (diff)
downloadantennapod-f0100e61ac633516082ea112363132c99f7c0b7a.zip
Chromecast rework (#5518)
Diffstat (limited to 'app')
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/CancelablePSMPCallback.java28
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/DefaultPSMPCallback.java69
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java4
-rw-r--r--app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java17
-rw-r--r--app/src/free/java/de/danoeh/antennapod/config/CastCallbackImpl.java7
-rw-r--r--app/src/free/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java14
-rw-r--r--app/src/main/AndroidManifest.xml3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java2
-rw-r--r--app/src/main/res/menu/cast_enabled.xml10
-rw-r--r--app/src/main/res/xml/preferences_playback.xml6
-rw-r--r--app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java157
-rw-r--r--app/src/play/java/de/danoeh/antennapod/config/CastCallbackImpl.java21
-rw-r--r--app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java480
-rw-r--r--app/src/play/java/de/danoeh/antennapod/fragment/CustomMRControllerDialogFragment.java15
-rw-r--r--app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java48
-rw-r--r--app/src/play/res/layout/media_router_controller.xml41
24 files changed, 70 insertions, 867 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 87dea29de..3dcf7fe1e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -116,6 +116,8 @@ dependencies {
implementation project(':net:sync:gpoddernet')
implementation project(':net:sync:model')
implementation project(':parser:feed')
+ implementation project(':playback:base')
+ implementation project(':playback:cast')
implementation project(':ui:app-start-intent')
implementation project(':ui:common')
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 9f7af3a16..2ab2361d7 100644
--- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
@@ -11,6 +11,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
+import de.danoeh.antennapod.playback.base.PlayerStatus;
import org.awaitility.Awaitility;
import org.hamcrest.Matcher;
import org.junit.After;
@@ -32,7 +33,6 @@ import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
-import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.IntentUtils;
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 2c164f131..4d57b9b43 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
@@ -1,9 +1,10 @@
package de.test.antennapod.service.playback;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import de.danoeh.antennapod.model.playback.MediaType;
-import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
import de.danoeh.antennapod.model.playback.Playable;
+import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer;
public class CancelablePSMPCallback implements PlaybackServiceMediaPlayer.PSMPCallback {
@@ -43,14 +44,6 @@ public class CancelablePSMPCallback implements PlaybackServiceMediaPlayer.PSMPCa
}
@Override
- public boolean onMediaPlayerInfo(int code, int resourceId) {
- if (isCancelled) {
- return true;
- }
- return originalCallback.onMediaPlayerInfo(code, resourceId);
- }
-
- @Override
public void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped, boolean playingNext) {
if (isCancelled) {
return;
@@ -82,6 +75,15 @@ public class CancelablePSMPCallback implements PlaybackServiceMediaPlayer.PSMPCa
return originalCallback.getNextInQueue(currentMedia);
}
+ @Nullable
+ @Override
+ public Playable findMedia(@NonNull String url) {
+ if (isCancelled) {
+ return null;
+ }
+ return originalCallback.findMedia(url);
+ }
+
@Override
public void onPlaybackEnded(MediaType mediaType, boolean stopPlaying) {
if (isCancelled) {
@@ -89,4 +91,12 @@ public class CancelablePSMPCallback implements PlaybackServiceMediaPlayer.PSMPCa
}
originalCallback.onPlaybackEnded(mediaType, stopPlaying);
}
+
+ @Override
+ public void ensureMediaInfoLoaded(@NonNull Playable media) {
+ if (isCancelled) {
+ return;
+ }
+ originalCallback.ensureMediaInfoLoaded(media);
+ }
} \ No newline at end of file
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 090a94d6e..fb55c7ad0 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
@@ -1,54 +1,59 @@
package de.test.antennapod.service.playback;
import androidx.annotation.NonNull;
-import androidx.annotation.StringRes;
+import androidx.annotation.Nullable;
import de.danoeh.antennapod.model.playback.MediaType;
-import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
import de.danoeh.antennapod.model.playback.Playable;
+import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer;
public class DefaultPSMPCallback implements PlaybackServiceMediaPlayer.PSMPCallback {
- @Override
- public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
+ @Override
+ public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
- }
+ }
- @Override
- public void shouldStop() {
+ @Override
+ public void shouldStop() {
- }
+ }
- @Override
- public void onMediaChanged(boolean reloadUI) {
+ @Override
+ public void onMediaChanged(boolean reloadUI) {
- }
+ }
- @Override
- public boolean onMediaPlayerInfo(int code, @StringRes int resourceId) {
- return false;
- }
+ @Override
+ public void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped, boolean playingNext) {
- @Override
- public void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped, boolean playingNext) {
+ }
- }
+ @Override
+ public void onPlaybackStart(@NonNull Playable playable, int position) {
- @Override
- public void onPlaybackStart(@NonNull Playable playable, int position) {
+ }
- }
+ @Override
+ public void onPlaybackPause(Playable playable, int position) {
- @Override
- public void onPlaybackPause(Playable playable, int position) {
+ }
- }
+ @Override
+ public Playable getNextInQueue(Playable currentMedia) {
+ return null;
+ }
- @Override
- public Playable getNextInQueue(Playable currentMedia) {
- return null;
- }
+ @Nullable
+ @Override
+ public Playable findMedia(@NonNull String url) {
+ return null;
+ }
- @Override
- public void onPlaybackEnded(MediaType mediaType, boolean stopPlaying) {
+ @Override
+ public void onPlaybackEnded(MediaType mediaType, boolean stopPlaying) {
- }
- } \ No newline at end of file
+ }
+
+ @Override
+ public void ensureMediaInfoLoaded(@NonNull Playable media) {
+ }
+} \ No newline at end of file
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
index 87a5fa65c..32298200e 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
@@ -5,6 +5,8 @@ import android.content.Context;
import androidx.test.filters.MediumTest;
import de.danoeh.antennapod.model.feed.VolumeAdaptionSetting;
+import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer;
+import de.danoeh.antennapod.playback.base.PlayerStatus;
import de.test.antennapod.EspressoTestUtils;
import junit.framework.AssertionFailedError;
@@ -24,8 +26,6 @@ import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.feed.FeedPreferences;
import de.danoeh.antennapod.core.service.playback.LocalPSMP;
-import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
-import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.model.playback.Playable;
import de.test.antennapod.util.service.download.HTTPBin;
diff --git a/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java b/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java
deleted file mode 100644
index 98d506f65..000000000
--- a/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import android.view.Menu;
-
-/**
- * Activity that allows for showing the MediaRouter button whenever there's a cast device in the
- * network.
- */
-public abstract class CastEnabledActivity extends AppCompatActivity {
- public static final String TAG = "CastEnabledActivity";
-
- public final void requestCastButton(Menu menu) {
- // no-op
- }
-}
diff --git a/app/src/free/java/de/danoeh/antennapod/config/CastCallbackImpl.java b/app/src/free/java/de/danoeh/antennapod/config/CastCallbackImpl.java
deleted file mode 100644
index fb23dfa1a..000000000
--- a/app/src/free/java/de/danoeh/antennapod/config/CastCallbackImpl.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.danoeh.antennapod.config;
-
-import de.danoeh.antennapod.core.CastCallbacks;
-
-class CastCallbackImpl implements CastCallbacks {
-
-}
diff --git a/app/src/free/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java b/app/src/free/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java
deleted file mode 100644
index e096f883f..000000000
--- a/app/src/free/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.danoeh.antennapod.preferences;
-
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.preferences.PlaybackPreferencesFragment;
-
-/**
- * Implements functions from PreferenceController that are flavor dependent.
- */
-public class PreferenceControllerFlavorHelper {
-
- public static void setupFlavoredUI(PlaybackPreferencesFragment ui) {
- ui.findPreference(UserPreferences.PREF_CAST_ENABLED).setEnabled(false);
- }
-}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 45c21ce6b..0f8242e63 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -54,6 +54,9 @@
<meta-data
android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAI3a05VToCTlqBymJrbFGaKQMvF-bBAuLsOdavBA"/>
+ <meta-data
+ android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
+ android:value="de.danoeh.antennapod.playback.cast.CastOptionsProvider" />
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
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 94270339d..7dc760e76 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -38,6 +38,7 @@ import com.bumptech.glide.Glide;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.snackbar.Snackbar;
+import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
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 f895f76bb..4ff2a5775 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -43,7 +43,6 @@ import de.danoeh.antennapod.event.playback.PlaybackServiceEvent;
import de.danoeh.antennapod.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;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.Converter;
@@ -62,6 +61,8 @@ import de.danoeh.antennapod.dialog.SleepTimerDialog;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.playback.Playable;
+import de.danoeh.antennapod.playback.base.PlayerStatus;
+import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
index a45eb5199..1f4f657b1 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
@@ -15,6 +15,5 @@ class ClientConfigurator {
ClientConfig.USER_AGENT = "AntennaPod/" + BuildConfig.VERSION_NAME;
ClientConfig.applicationCallbacks = new ApplicationCallbacksImpl();
ClientConfig.downloadServiceCallbacks = new DownloadServiceCallbacksImpl();
- ClientConfig.castCallbacks = new CastCallbackImpl();
}
}
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 77d450f70..95e2eb1aa 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
@@ -32,6 +32,7 @@ import de.danoeh.antennapod.event.playback.PlaybackServiceEvent;
import de.danoeh.antennapod.event.PlayerErrorEvent;
import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent;
import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
+import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -41,7 +42,6 @@ import java.text.NumberFormat;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.CastEnabledActivity;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.event.FavoritesEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
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 0d7aadbd0..04ad6e2bd 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -17,6 +17,7 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import de.danoeh.antennapod.playback.base.PlayerStatus;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -24,7 +25,6 @@ import org.greenrobot.eventbus.ThreadMode;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.ChaptersListAdapter;
import de.danoeh.antennapod.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;
import de.danoeh.antennapod.model.feed.Chapter;
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 d1ab44572..1e24d62f7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -23,9 +23,9 @@ import de.danoeh.antennapod.model.playback.MediaType;
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
-import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.playback.base.PlayerStatus;
import de.danoeh.antennapod.view.PlayButton;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
index 9a86a4b3c..7fa2ed4d1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
@@ -16,7 +16,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
-import de.danoeh.antennapod.preferences.PreferenceControllerFlavorHelper;
import java.util.Map;
import org.greenrobot.eventbus.EventBus;
@@ -31,7 +30,6 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat {
addPreferencesFromResource(R.xml.preferences_playback);
setupPlaybackScreen();
- PreferenceControllerFlavorHelper.setupFlavoredUI(this);
buildSmartMarkAsPlayedPreference();
}
diff --git a/app/src/main/res/menu/cast_enabled.xml b/app/src/main/res/menu/cast_enabled.xml
deleted file mode 100644
index d6e85c311..000000000
--- a/app/src/main/res/menu/cast_enabled.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:custom="http://schemas.android.com/apk/res-auto">
-
- <item
- android:id="@+id/media_route_menu_item"
- android:title="@string/cast_media_route_menu_title"
- custom:actionProviderClass="de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider"
- custom:showAsAction="ifRoom"/>
-</menu> \ No newline at end of file
diff --git a/app/src/main/res/xml/preferences_playback.xml b/app/src/main/res/xml/preferences_playback.xml
index 59bdaedcb..add9e8d4c 100644
--- a/app/src/main/res/xml/preferences_playback.xml
+++ b/app/src/main/res/xml/preferences_playback.xml
@@ -127,11 +127,5 @@
android:title="@string/media_player"
android:summary="@string/pref_media_player_message"
android:entryValues="@array/media_player_values"/>
- <SwitchPreferenceCompat
- android:defaultValue="false"
- android:enabled="true"
- android:key="prefCast"
- android:summary="@string/pref_cast_message"
- android:title="@string/pref_cast_title"/>
</PreferenceCategory>
</PreferenceScreen>
diff --git a/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java b/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java
deleted file mode 100644
index 753feb3e7..000000000
--- a/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.content.SharedPreferences;
-import android.media.AudioManager;
-import android.os.Bundle;
-import androidx.preference.PreferenceManager;
-import androidx.appcompat.app.AppCompatActivity;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import com.google.android.gms.cast.ApplicationMetadata;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.cast.CastButtonVisibilityManager;
-import de.danoeh.antennapod.core.cast.CastConsumer;
-import de.danoeh.antennapod.core.cast.CastManager;
-import de.danoeh.antennapod.core.cast.DefaultCastConsumer;
-import de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Activity that allows for showing the MediaRouter button whenever there's a cast device in the
- * network.
- */
-public abstract class CastEnabledActivity extends AppCompatActivity
- implements SharedPreferences.OnSharedPreferenceChangeListener {
- public static final String TAG = "CastEnabledActivity";
-
- private CastConsumer castConsumer;
- private CastManager castManager;
- private final List<CastButtonVisibilityManager> castButtons = new ArrayList<>();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (!CastManager.isInitialized()) {
- return;
- }
-
- PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
- .registerOnSharedPreferenceChangeListener(this);
-
- castConsumer = new DefaultCastConsumer() {
- @Override
- public void onApplicationConnected(ApplicationMetadata appMetadata, String sessionId, boolean wasLaunched) {
- onCastConnectionChanged(true);
- }
-
- @Override
- public void onDisconnected() {
- onCastConnectionChanged(false);
- }
- };
- castManager = CastManager.getInstance();
- castManager.addCastConsumer(castConsumer);
- CastButtonVisibilityManager castButtonVisibilityManager = new CastButtonVisibilityManager(castManager);
- castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled());
- onCastConnectionChanged(castManager.isConnected());
- castButtons.add(castButtonVisibilityManager);
- }
-
- @Override
- protected void onDestroy() {
- if (!CastManager.isInitialized()) {
- super.onDestroy();
- return;
- }
- PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
- .unregisterOnSharedPreferenceChangeListener(this);
- castManager.removeCastConsumer(castConsumer);
- super.onDestroy();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if (!CastManager.isInitialized()) {
- return;
- }
- for (CastButtonVisibilityManager castButton : castButtons) {
- castButton.setResumed(true);
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- if (!CastManager.isInitialized()) {
- return;
- }
- for (CastButtonVisibilityManager castButton : castButtons) {
- castButton.setResumed(false);
- }
- }
-
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (UserPreferences.PREF_CAST_ENABLED.equals(key)) {
- boolean newValue = UserPreferences.isCastEnabled();
- Log.d(TAG, "onSharedPreferenceChanged(), isCastEnabled set to " + newValue);
- for (CastButtonVisibilityManager castButton : castButtons) {
- castButton.setPrefEnabled(newValue);
- }
- // PlaybackService has its own listener, so if it's active we don't have to take action here.
- if (!newValue && !PlaybackService.isRunning) {
- CastManager.getInstance().disconnect();
- }
- }
- }
-
- private void onCastConnectionChanged(boolean connected) {
- if (connected) {
- for (CastButtonVisibilityManager castButton : castButtons) {
- castButton.onConnected();
- }
- setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
- } else {
- for (CastButtonVisibilityManager castButton : castButtons) {
- castButton.onDisconnected();
- }
- setVolumeControlStream(AudioManager.STREAM_MUSIC);
- }
- }
-
- /**
- * Should be called by any activity or fragment for which the cast button should be shown.
- */
- public final void requestCastButton(Menu menu) {
- if (!CastManager.isInitialized()) {
- return;
- }
-
- MenuItem mediaRouteButton = menu.findItem(R.id.media_route_menu_item);
- if (mediaRouteButton == null) {
- getMenuInflater().inflate(R.menu.cast_enabled, menu);
- mediaRouteButton = menu.findItem(R.id.media_route_menu_item);
- }
-
- SwitchableMediaRouteActionProvider mediaRouteActionProvider =
- CastManager.getInstance().addMediaRouterButton(mediaRouteButton);
- CastButtonVisibilityManager castButtonVisibilityManager =
- new CastButtonVisibilityManager(CastManager.getInstance());
- castButtonVisibilityManager.setMenu(menu);
- castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled());
- castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider;
- castButtonVisibilityManager.setResumed(true);
- castButtonVisibilityManager.requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
- mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable());
- }
-}
diff --git a/app/src/play/java/de/danoeh/antennapod/config/CastCallbackImpl.java b/app/src/play/java/de/danoeh/antennapod/config/CastCallbackImpl.java
deleted file mode 100644
index 2a879c62d..000000000
--- a/app/src/play/java/de/danoeh/antennapod/config/CastCallbackImpl.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.danoeh.antennapod.config;
-
-import androidx.annotation.NonNull;
-import androidx.mediarouter.app.MediaRouteControllerDialogFragment;
-import androidx.mediarouter.app.MediaRouteDialogFactory;
-
-import de.danoeh.antennapod.core.CastCallbacks;
-import de.danoeh.antennapod.fragment.CustomMRControllerDialogFragment;
-
-public class CastCallbackImpl implements CastCallbacks {
- @Override
- public MediaRouteDialogFactory getMediaRouterDialogFactory() {
- return new MediaRouteDialogFactory() {
- @NonNull
- @Override
- public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
- return new CustomMRControllerDialogFragment();
- }
- };
- }
-}
diff --git a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
deleted file mode 100644
index 6d8450a18..000000000
--- a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
+++ /dev/null
@@ -1,480 +0,0 @@
-package de.danoeh.antennapod.dialog;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import androidx.annotation.NonNull;
-import android.support.v4.media.MediaDescriptionCompat;
-import android.support.v4.media.MediaMetadataCompat;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import androidx.core.util.Pair;
-import androidx.core.view.MarginLayoutParamsCompat;
-import androidx.core.view.accessibility.AccessibilityEventCompat;
-import androidx.mediarouter.app.MediaRouteControllerDialog;
-import androidx.palette.graphics.Palette;
-import androidx.mediarouter.media.MediaRouter;
-import androidx.appcompat.widget.AppCompatImageView;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.FrameLayout;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.request.RequestOptions;
-import com.bumptech.glide.request.target.Target;
-
-import java.util.concurrent.ExecutionException;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.glide.ApGlideSettings;
-import io.reactivex.Observable;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.schedulers.Schedulers;
-
-public class CustomMRControllerDialog extends MediaRouteControllerDialog {
- public static final String TAG = "CustomMRContrDialog";
-
- private MediaRouter mediaRouter;
- private MediaSessionCompat.Token token;
-
- private ImageView artView;
- private TextView titleView;
- private TextView subtitleView;
- private ImageButton playPauseButton;
- private LinearLayout rootView;
-
- private boolean viewsCreated = false;
-
- private Disposable fetchArtSubscription;
-
- private MediaControllerCompat mediaController;
- private MediaControllerCompat.Callback mediaControllerCallback;
-
- public CustomMRControllerDialog(Context context) {
- this(context, 0);
- }
-
- private CustomMRControllerDialog(Context context, int theme) {
- super(context, theme);
- mediaRouter = MediaRouter.getInstance(getContext());
- token = mediaRouter.getMediaSessionToken();
- try {
- if (token != null) {
- mediaController = new MediaControllerCompat(getContext(), token);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error creating media controller", e);
- }
-
- if (mediaController != null) {
- mediaControllerCallback = new MediaControllerCompat.Callback() {
- @Override
- public void onSessionDestroyed() {
- if (mediaController != null) {
- mediaController.unregisterCallback(mediaControllerCallback);
- mediaController = null;
- }
- }
-
- @Override
- public void onMetadataChanged(MediaMetadataCompat metadata) {
- updateViews();
- }
-
- @Override
- public void onPlaybackStateChanged(PlaybackStateCompat state) {
- updateState();
- }
- };
- mediaController.registerCallback(mediaControllerCallback);
- }
- }
-
- @Override
- public View onCreateMediaControlView(Bundle savedInstanceState) {
- boolean landscape = getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
- if (landscape) {
- /*
- * When a horizontal LinearLayout measures itself, it first measures its children and
- * settles their widths on the first pass, and only then figures out its height, never
- * revisiting the widths measurements.
- * When one has a child view that imposes a certain aspect ratio (such as an ImageView),
- * then its width and height are related to each other, and so if one allows for a large
- * height, then it will request for itself a large width as well. However, on the first
- * child measurement, the LinearLayout imposes a very relaxed height bound, that the
- * child uses to tell the width it wants, a value which the LinearLayout will interpret
- * as final, even though the child will want to change it once a more restrictive height
- * bound is imposed later.
- *
- * Our solution is, given that the heights of the children do not depend on their widths
- * in this case, we first figure out the layout's height and only then perform the
- * usual sequence of measurements.
- *
- * Note: this solution does not take into account any vertical paddings nor children's
- * vertical margins in determining the height, as this View as well as its children are
- * defined in code and no paddings/margins that would influence these computations are
- * introduced.
- *
- * There were no resources online for this type of issue as far as I could gather.
- */
- rootView = new LinearLayout(getContext()) {
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // We'd like to find the overall height before adjusting the widths within the LinearLayout
- int maxHeight = Integer.MIN_VALUE;
- if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
- for (int i = 0; i < getChildCount(); i++) {
- int height = Integer.MIN_VALUE;
- View child = getChildAt(i);
- ViewGroup.LayoutParams lp = child.getLayoutParams();
- // we only measure children whose layout_height is not MATCH_PARENT
- if (lp.height >= 0) {
- height = lp.height;
- } else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
- child.measure(widthMeasureSpec, heightMeasureSpec);
- height = child.getMeasuredHeight();
- }
- maxHeight = Math.max(maxHeight, height);
- }
- }
- if (maxHeight > 0) {
- super.onMeasure(widthMeasureSpec,
- MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY));
- } else {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- }
- };
- rootView.setOrientation(LinearLayout.HORIZONTAL);
- } else {
- rootView = new LinearLayout(getContext());
- rootView.setOrientation(LinearLayout.VERTICAL);
- }
- FrameLayout.LayoutParams rootParams = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- rootParams.setMargins(0, 0, 0,
- getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_bottom_margin));
- rootView.setLayoutParams(rootParams);
-
- // Start the session activity when a content item (album art, title or subtitle) is clicked.
- View.OnClickListener onClickListener = v -> {
- if (mediaController != null) {
- PendingIntent pi = mediaController.getSessionActivity();
- if (pi != null) {
- try {
- pi.send();
- dismiss();
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, pi + " was not sent, it had been canceled.");
- }
- }
- }
- };
-
- LinearLayout.LayoutParams artParams;
- /*
- * On portrait orientation, we want to limit the artView's height to 9/16 of the available
- * width. Reason is that we need to choose the height wisely otherwise we risk the dialog
- * being much larger than the screen, and there doesn't seem to be a good way to know the
- * available height beforehand.
- *
- * On landscape orientation, we want to limit the artView's width to its available height.
- * Otherwise, horizontal images would take too much space and severely restrict the space
- * for episode title and play/pause button.
- *
- * Internal implementation of ImageView only uses the source image's aspect ratio, but we
- * want to impose our own and fallback to the source image's when it is more favorable.
- * Solutions were inspired, among other similar sources, on
- * http://stackoverflow.com/questions/18077325/scale-image-to-fill-imageview-width-and-keep-aspect-ratio
- */
- if (landscape) {
- artView = new AppCompatImageView(getContext()) {
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int desiredWidth = widthMeasureSpec;
- int desiredMeasureMode = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY ?
- MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
- if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY) {
- Drawable drawable = getDrawable();
- if (drawable != null) {
- int intrHeight = drawable.getIntrinsicHeight();
- int intrWidth = drawable.getIntrinsicWidth();
- int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
- if (intrHeight < intrWidth) {
- desiredWidth = MeasureSpec.makeMeasureSpec(
- originalHeight, desiredMeasureMode);
- } else {
- desiredWidth = MeasureSpec.makeMeasureSpec(
- Math.round((float) originalHeight * intrWidth / intrHeight),
- desiredMeasureMode);
- }
- }
- }
- super.onMeasure(desiredWidth, heightMeasureSpec);
- }
- };
- artParams = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
- MarginLayoutParamsCompat.setMarginStart(artParams,
- getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_playback_control_horizontal_spacing));
- } else {
- artView = new AppCompatImageView(getContext()) {
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int desiredHeight = heightMeasureSpec;
- if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
- Drawable drawable = getDrawable();
- if (drawable != null) {
- int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
- int intrHeight = drawable.getIntrinsicHeight();
- int intrWidth = drawable.getIntrinsicWidth();
- float scale;
- if (intrHeight*16 > intrWidth*9) {
- // image is taller than 16:9
- scale = (float) originalWidth * 9 / 16 / intrHeight;
- } else {
- // image is more horizontal than 16:9
- scale = (float) originalWidth / intrWidth;
- }
- desiredHeight = MeasureSpec.makeMeasureSpec(
- Math.round(intrHeight * scale),
- MeasureSpec.EXACTLY);
- }
- }
- super.onMeasure(widthMeasureSpec, desiredHeight);
- }
- };
- artParams = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- }
- // When we fetch the bitmap, we want to know if we should set a background color or not.
- artView.setTag(landscape);
-
- artView.setScaleType(ImageView.ScaleType.FIT_CENTER);
- artView.setOnClickListener(onClickListener);
-
- artView.setLayoutParams(artParams);
- rootView.addView(artView);
-
- ViewGroup wrapper = rootView;
-
- if (landscape) {
- // Here we wrap with a frame layout because we want to set different layout parameters
- // for landscape orientation.
- wrapper = new FrameLayout(getContext());
- wrapper.setLayoutParams(new LinearLayout.LayoutParams(
- 0,
- ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
- rootView.addView(wrapper);
- rootView.setWeightSum(1f);
- }
-
- View playbackControlLayout = View.inflate(getContext(), R.layout.media_router_controller, wrapper);
-
- titleView = playbackControlLayout.findViewById(R.id.mrc_control_title);
- subtitleView = playbackControlLayout.findViewById(R.id.mrc_control_subtitle);
- playbackControlLayout.findViewById(R.id.mrc_control_title_container).setOnClickListener(onClickListener);
- playPauseButton = playbackControlLayout.findViewById(R.id.mrc_control_play_pause);
- playPauseButton.setOnClickListener(v -> {
- PlaybackStateCompat state;
- if (mediaController != null && (state = mediaController.getPlaybackState()) != null) {
- boolean isPlaying = state.getState() == PlaybackStateCompat.STATE_PLAYING;
- if (isPlaying) {
- mediaController.getTransportControls().pause();
- } else {
- mediaController.getTransportControls().play();
- }
- // Announce the action for accessibility.
- AccessibilityManager accessibilityManager = (AccessibilityManager)
- getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
- if (accessibilityManager != null && accessibilityManager.isEnabled()) {
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
- event.setPackageName(getContext().getPackageName());
- event.setClassName(getClass().getName());
- int resId = isPlaying ? R.string.mr_controller_pause : R.string.mr_controller_play;
- event.getText().add(getContext().getString(resId));
- accessibilityManager.sendAccessibilityEvent(event);
- }
- }
- });
-
- viewsCreated = true;
- updateViews();
- return rootView;
- }
-
- @Override
- public void onDetachedFromWindow() {
- if (fetchArtSubscription != null) {
- fetchArtSubscription.dispose();
- fetchArtSubscription = null;
- }
- super.onDetachedFromWindow();
- }
-
- private void updateViews() {
- if (!viewsCreated || token == null || mediaController == null) {
- rootView.setVisibility(View.GONE);
- return;
- }
- MediaMetadataCompat metadata = mediaController.getMetadata();
- MediaDescriptionCompat description = metadata == null ? null : metadata.getDescription();
- if (description == null) {
- rootView.setVisibility(View.GONE);
- return;
- }
-
- PlaybackStateCompat state = mediaController.getPlaybackState();
- MediaRouter.RouteInfo route = MediaRouter.getInstance(getContext()).getSelectedRoute();
-
- CharSequence title = description.getTitle();
- boolean hasTitle = !TextUtils.isEmpty(title);
- CharSequence subtitle = description.getSubtitle();
- boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
-
- boolean showTitle = false;
- boolean showSubtitle = false;
- if (route.getPresentationDisplay() != null &&
- route.getPresentationDisplay().getDisplayId() != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) {
- // The user is currently casting screen.
- titleView.setText(R.string.mr_controller_casting_screen);
- showTitle = true;
- } else if (state == null || state.getState() == PlaybackStateCompat.STATE_NONE) {
- // Show "No media selected" as we don't yet know the playback state.
- // (Only exception is bluetooth where we don't show anything.)
- if (!route.isBluetooth()) {
- titleView.setText(R.string.mr_controller_no_media_selected);
- showTitle = true;
- }
- } else if (!hasTitle && !hasSubtitle) {
- titleView.setText(R.string.mr_controller_no_info_available);
- showTitle = true;
- } else {
- if (hasTitle) {
- titleView.setText(title);
- showTitle = true;
- }
- if (hasSubtitle) {
- subtitleView.setText(subtitle);
- showSubtitle = true;
- }
- }
- if (showSubtitle) {
- titleView.setSingleLine();
- } else {
- titleView.setMaxLines(2);
- }
- titleView.setVisibility(showTitle ? View.VISIBLE : View.GONE);
- subtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
-
- updateState();
-
- if(rootView.getVisibility() != View.VISIBLE) {
- artView.setVisibility(View.GONE);
- rootView.setVisibility(View.VISIBLE);
- }
-
- if (fetchArtSubscription != null) {
- fetchArtSubscription.dispose();
- }
-
- fetchArtSubscription = Observable.fromCallable(() -> fetchArt(description))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> {
- fetchArtSubscription = null;
- if (artView == null) {
- return;
- }
- if (result.first != null) {
- if (!((Boolean) artView.getTag())) {
- artView.setBackgroundColor(result.second);
- }
- artView.setImageBitmap(result.first);
- artView.setVisibility(View.VISIBLE);
- } else {
- artView.setVisibility(View.GONE);
- }
- }, error -> Log.e(TAG, Log.getStackTraceString(error)));
-
- }
-
- private void updateState() {
- PlaybackStateCompat state;
- if (!viewsCreated || mediaController == null ||
- (state = mediaController.getPlaybackState()) == null) {
- return;
- }
- boolean isPlaying = state.getState() == PlaybackStateCompat.STATE_BUFFERING
- || state.getState() == PlaybackStateCompat.STATE_PLAYING;
- boolean supportsPlay = (state.getActions() & (PlaybackStateCompat.ACTION_PLAY
- | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
- boolean supportsPause = (state.getActions() & (PlaybackStateCompat.ACTION_PAUSE
- | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
- if (isPlaying && supportsPause) {
- playPauseButton.setVisibility(View.VISIBLE);
- playPauseButton.setImageResource(getThemeResource(getContext(), R.attr.mediaRoutePauseDrawable));
- playPauseButton.setContentDescription(getContext().getResources().getText(R.string.mr_controller_pause));
- } else if (!isPlaying && supportsPlay) {
- playPauseButton.setVisibility(View.VISIBLE);
- playPauseButton.setImageResource(getThemeResource(getContext(), R.attr.mediaRoutePlayDrawable));
- playPauseButton.setContentDescription(getContext().getResources().getText(R.string.mr_controller_play));
- } else {
- playPauseButton.setVisibility(View.GONE);
- }
- }
-
- private static int getThemeResource(Context context, int attr) {
- TypedValue value = new TypedValue();
- return context.getTheme().resolveAttribute(attr, value, true) ? value.resourceId : 0;
- }
-
- @NonNull
- private Pair<Bitmap, Integer> fetchArt(@NonNull MediaDescriptionCompat description) {
- Bitmap iconBitmap = description.getIconBitmap();
- Uri iconUri = description.getIconUri();
- Bitmap art = null;
- if (iconBitmap != null) {
- art = iconBitmap;
- } else if (iconUri != null) {
- try {
- art = Glide.with(getContext().getApplicationContext())
- .asBitmap()
- .load(iconUri.toString())
- .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY))
- .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
- .get();
- } catch (InterruptedException | ExecutionException e) {
- Log.e(TAG, "Image art load failed", e);
- }
- }
- int backgroundColor = 0;
- if (art != null && art.getWidth()*9 < art.getHeight()*16) {
- // Portrait art requires dominant color as background color.
- Palette palette = new Palette.Builder(art).maximumColorCount(1).generate();
- backgroundColor = palette.getSwatches().isEmpty()
- ? 0 : palette.getSwatches().get(0).getRgb();
- }
- return new Pair<>(art, backgroundColor);
- }
-}
diff --git a/app/src/play/java/de/danoeh/antennapod/fragment/CustomMRControllerDialogFragment.java b/app/src/play/java/de/danoeh/antennapod/fragment/CustomMRControllerDialogFragment.java
deleted file mode 100644
index dad7b0bfd..000000000
--- a/app/src/play/java/de/danoeh/antennapod/fragment/CustomMRControllerDialogFragment.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.danoeh.antennapod.fragment;
-
-import android.content.Context;
-import android.os.Bundle;
-import androidx.mediarouter.app.MediaRouteControllerDialog;
-import androidx.mediarouter.app.MediaRouteControllerDialogFragment;
-
-import de.danoeh.antennapod.dialog.CustomMRControllerDialog;
-
-public class CustomMRControllerDialogFragment extends MediaRouteControllerDialogFragment {
- @Override
- public MediaRouteControllerDialog onCreateControllerDialog(Context context, Bundle savedInstanceState) {
- return new CustomMRControllerDialog(context);
- }
-}
diff --git a/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java b/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java
deleted file mode 100644
index b51fb40b0..000000000
--- a/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerFlavorHelper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.danoeh.antennapod.preferences;
-
-import android.content.Context;
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-
-import com.google.android.gms.common.ConnectionResult;
-import com.google.android.gms.common.GoogleApiAvailability;
-
-import de.danoeh.antennapod.PodcastApp;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.preferences.PlaybackPreferencesFragment;
-
-/**
- * Implements functions from PreferenceController that are flavor dependent.
- */
-public class PreferenceControllerFlavorHelper {
-
- public static void setupFlavoredUI(PlaybackPreferencesFragment ui) {
- //checks whether Google Play Services is installed on the device (condition necessary for Cast support)
- ui.findPreference(UserPreferences.PREF_CAST_ENABLED).setOnPreferenceChangeListener((preference, o) -> {
- if (o instanceof Boolean && ((Boolean) o)) {
- final int googlePlayServicesCheck = GoogleApiAvailability.getInstance()
- .isGooglePlayServicesAvailable(ui.getActivity());
- if (googlePlayServicesCheck == ConnectionResult.SUCCESS) {
- displayRestartRequiredDialog(ui.requireContext());
- return true;
- } else {
- GoogleApiAvailability.getInstance()
- .getErrorDialog(ui.getActivity(), googlePlayServicesCheck, 0)
- .show();
- return false;
- }
- }
- return true;
- });
- }
-
- private static void displayRestartRequiredDialog(@NonNull Context context) {
- AlertDialog.Builder dialog = new AlertDialog.Builder(context);
- dialog.setTitle(android.R.string.dialog_alert_title);
- dialog.setMessage(R.string.pref_restart_required);
- dialog.setPositiveButton(android.R.string.ok, (dialog1, which) -> PodcastApp.forceRestart());
- dialog.setCancelable(false);
- dialog.show();
- }
-}
diff --git a/app/src/play/res/layout/media_router_controller.xml b/app/src/play/res/layout/media_router_controller.xml
deleted file mode 100644
index bdb1b1cc2..000000000
--- a/app/src/play/res/layout/media_router_controller.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/mrc_playback_control"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/media_router_controller_playback_control_vertical_padding"
- android:paddingBottom="@dimen/media_router_controller_playback_control_vertical_padding"
- android:paddingLeft="@dimen/media_router_controller_playback_control_start_padding"
- android:paddingStart="@dimen/media_router_controller_playback_control_start_padding"
- android:paddingRight="@dimen/media_router_controller_playback_control_horizontal_spacing"
- android:paddingEnd="@dimen/media_router_controller_playback_control_horizontal_spacing">
- <ImageButton android:id="@+id/mrc_control_play_pause"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/media_router_controller_playback_control_horizontal_spacing"
- android:layout_marginStart="@dimen/media_router_controller_playback_control_horizontal_spacing"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"
- android:contentDescription="@string/mr_controller_play"
- android:background="?android:attr/selectableItemBackground"/>
-
- <LinearLayout android:id="@+id/mrc_control_title_container"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_toLeftOf="@id/mrc_control_play_pause"
- android:layout_toStartOf="@id/mrc_control_play_pause"
- android:layout_centerVertical="true">
- <TextView android:id="@+id/mrc_control_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.MediaRouter.PrimaryText"/>
- <TextView android:id="@+id/mrc_control_subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText"
- android:singleLine="true" />
- </LinearLayout>
-</RelativeLayout>