diff options
author | ByteHamster <ByteHamster@users.noreply.github.com> | 2021-11-28 22:19:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-28 22:19:14 +0100 |
commit | f0100e61ac633516082ea112363132c99f7c0b7a (patch) | |
tree | f7598c0cee85780b409ab895a8041d1607eec312 /app | |
parent | af2835c59dcb0473aba7a48b38f5abe28dca34d3 (diff) | |
download | AntennaPod-f0100e61ac633516082ea112363132c99f7c0b7a.zip |
Chromecast rework (#5518)
Diffstat (limited to 'app')
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> |