Reworked cast button handling
This commit is contained in:
parent
a989db586a
commit
9e84a06260
|
@ -2,6 +2,8 @@ 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.
|
||||
|
@ -9,7 +11,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||
public abstract class CastEnabledActivity extends AppCompatActivity {
|
||||
public static final String TAG = "CastEnabledActivity";
|
||||
|
||||
public final void requestCastButton(int showAsAction) {
|
||||
public final void requestCastButton(Menu menu) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
|
|
@ -324,30 +324,6 @@ public class MainActivity extends CastEnabledActivity {
|
|||
Glide.get(this).clearMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
boolean retVal = super.onCreateOptionsMenu(menu);
|
||||
if (Flavors.FLAVOR == Flavors.PLAY) {
|
||||
switch (NavDrawerFragment.getLastNavFragment(this)) {
|
||||
case QueueFragment.TAG:
|
||||
case EpisodesFragment.TAG:
|
||||
case AudioPlayerFragment.TAG:
|
||||
requestCastButton(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
return retVal;
|
||||
case DownloadsFragment.TAG:
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
case AddFeedFragment.TAG:
|
||||
case SubscriptionFragment.TAG:
|
||||
return retVal;
|
||||
default:
|
||||
requestCastButton(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
return retVal;
|
||||
}
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (drawerToggle.onOptionsItemSelected(item)) {
|
||||
|
|
|
@ -295,9 +295,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
if (Flavors.FLAVOR == Flavors.PLAY) {
|
||||
requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
}
|
||||
requestCastButton(menu);
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.mediaplayer, menu);
|
||||
return true;
|
||||
|
|
|
@ -22,6 +22,7 @@ import androidx.fragment.app.FragmentPagerAdapter;
|
|||
import androidx.viewpager.widget.ViewPager;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.CastEnabledActivity;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.event.FavoritesEvent;
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
|
@ -423,7 +424,6 @@ public class AudioPlayerFragment extends Fragment implements
|
|||
|
||||
public void setupOptionsMenu() {
|
||||
if (toolbar.getMenu().size() == 0) {
|
||||
//toolbar.inflateMenu(R.menu.cast_enabled);
|
||||
toolbar.inflateMenu(R.menu.mediaplayer);
|
||||
}
|
||||
if (controller == null) {
|
||||
|
@ -439,17 +439,7 @@ public class AudioPlayerFragment extends Fragment implements
|
|||
toolbar.getMenu().findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive());
|
||||
toolbar.getMenu().findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive());
|
||||
|
||||
/*MenuItem mediaRouteButton = toolbar.getMenu().findItem(R.id.media_route_menu_item);
|
||||
SwitchableMediaRouteActionProvider mediaRouteActionProvider =
|
||||
CastManager.getInstance().addMediaRouterButton(mediaRouteButton);
|
||||
CastEnabledActivity.CastButtonVisibilityManager castButtonVisibilityManager =
|
||||
new CastEnabledActivity.CastButtonVisibilityManager(CastManager.getInstance());
|
||||
castButtonVisibilityManager.setMenu(toolbar.getMenu());
|
||||
castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled());
|
||||
castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider;
|
||||
castButtonVisibilityManager.setResumed(true);
|
||||
castButtonVisibilityManager.requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable());*/
|
||||
((CastEnabledActivity) getActivity()).requestCastButton(toolbar.getMenu());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -146,9 +146,6 @@ public class ItemPagerFragment extends Fragment {
|
|||
return;
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
if (Flavors.FLAVOR == Flavors.PLAY) {
|
||||
((CastEnabledActivity) getActivity()).requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
}
|
||||
inflater.inflate(R.menu.feeditem_options, menu);
|
||||
if (item.hasMedia()) {
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item);
|
||||
|
|
|
@ -136,8 +136,8 @@
|
|||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="@dimen/audioplayer_playercontrols_length_big"
|
||||
android:layout_height="@dimen/audioplayer_playercontrols_length_big"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:id="@+id/progLoading"
|
||||
|
|
|
@ -4,8 +4,6 @@ import android.content.SharedPreferences;
|
|||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
|
@ -14,6 +12,7 @@ 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;
|
||||
|
@ -21,6 +20,9 @@ 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.
|
||||
|
@ -31,8 +33,7 @@ public abstract class CastEnabledActivity extends AppCompatActivity
|
|||
|
||||
private CastConsumer castConsumer;
|
||||
private CastManager castManager;
|
||||
private SwitchableMediaRouteActionProvider mediaRouteActionProvider;
|
||||
private CastButtonVisibilityManager castButtonVisibilityManager;
|
||||
private final List<CastButtonVisibilityManager> castButtons = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -58,9 +59,10 @@ public abstract class CastEnabledActivity extends AppCompatActivity
|
|||
};
|
||||
castManager = CastManager.getInstance();
|
||||
castManager.addCastConsumer(castConsumer);
|
||||
castButtonVisibilityManager = new CastButtonVisibilityManager(castManager);
|
||||
CastButtonVisibilityManager castButtonVisibilityManager = new CastButtonVisibilityManager(castManager);
|
||||
castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled());
|
||||
onCastConnectionChanged(castManager.isConnected());
|
||||
castButtons.add(castButtonVisibilityManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,47 +77,15 @@ public abstract class CastEnabledActivity extends AppCompatActivity
|
|||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
if (!CastManager.isInitialized()) {
|
||||
return true;
|
||||
}
|
||||
getMenuInflater().inflate(R.menu.cast_enabled, menu);
|
||||
castButtonVisibilityManager.setMenu(menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
if (!CastManager.isInitialized()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MenuItem mediaRouteButton = menu.findItem(R.id.media_route_menu_item);
|
||||
if (mediaRouteButton == null) {
|
||||
Log.wtf(TAG, "MediaRoute item could not be found on the menu!", new Exception());
|
||||
mediaRouteActionProvider = null;
|
||||
return true;
|
||||
}
|
||||
mediaRouteActionProvider = castManager.addMediaRouterButton(mediaRouteButton);
|
||||
if (mediaRouteActionProvider != null) {
|
||||
castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider;
|
||||
mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (!CastManager.isInitialized()) {
|
||||
return;
|
||||
}
|
||||
castButtonVisibilityManager.setResumed(true);
|
||||
for (CastButtonVisibilityManager castButton : castButtons) {
|
||||
castButton.setResumed(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -124,7 +94,9 @@ public abstract class CastEnabledActivity extends AppCompatActivity
|
|||
if (!CastManager.isInitialized()) {
|
||||
return;
|
||||
}
|
||||
castButtonVisibilityManager.setResumed(false);
|
||||
for (CastButtonVisibilityManager castButton : castButtons) {
|
||||
castButton.setResumed(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,7 +105,9 @@ public abstract class CastEnabledActivity extends AppCompatActivity
|
|||
if (UserPreferences.PREF_CAST_ENABLED.equals(key)) {
|
||||
boolean newValue = UserPreferences.isCastEnabled();
|
||||
Log.d(TAG, "onSharedPreferenceChanged(), isCastEnabled set to " + newValue);
|
||||
castButtonVisibilityManager.setPrefEnabled(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();
|
||||
|
@ -143,135 +117,41 @@ public abstract class CastEnabledActivity extends AppCompatActivity
|
|||
|
||||
private void onCastConnectionChanged(boolean connected) {
|
||||
if (connected) {
|
||||
castButtonVisibilityManager.onConnected();
|
||||
for (CastButtonVisibilityManager castButton : castButtons) {
|
||||
castButton.onConnected();
|
||||
}
|
||||
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
|
||||
} else {
|
||||
castButtonVisibilityManager.onDisconnected();
|
||||
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.
|
||||
*
|
||||
* @param showAsAction refer to {@link MenuItem#setShowAsAction(int)}
|
||||
*/
|
||||
public final void requestCastButton(int showAsAction) {
|
||||
public final void requestCastButton(Menu menu) {
|
||||
if (!CastManager.isInitialized()) {
|
||||
return;
|
||||
}
|
||||
castButtonVisibilityManager.requestCastButton(showAsAction);
|
||||
}
|
||||
|
||||
public static class CastButtonVisibilityManager {
|
||||
private final CastManager castManager;
|
||||
private volatile boolean prefEnabled = false;
|
||||
private volatile boolean viewRequested = false;
|
||||
private volatile boolean resumed = false;
|
||||
private volatile boolean connected = false;
|
||||
private volatile int showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM;
|
||||
private Menu menu;
|
||||
public SwitchableMediaRouteActionProvider mediaRouteActionProvider;
|
||||
|
||||
public CastButtonVisibilityManager(CastManager castManager) {
|
||||
this.castManager = castManager;
|
||||
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);
|
||||
}
|
||||
|
||||
public synchronized void setPrefEnabled(boolean newValue) {
|
||||
if (prefEnabled != newValue && resumed && (viewRequested || connected)) {
|
||||
if (newValue) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
prefEnabled = newValue;
|
||||
if (mediaRouteActionProvider != null) {
|
||||
mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setResumed(boolean newValue) {
|
||||
if (resumed == newValue) {
|
||||
Log.e(TAG, "resumed should never change to the same value");
|
||||
return;
|
||||
}
|
||||
resumed = newValue;
|
||||
if (prefEnabled && (viewRequested || connected)) {
|
||||
if (resumed) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setViewRequested(boolean newValue) {
|
||||
if (viewRequested != newValue && resumed && prefEnabled && !connected) {
|
||||
if (newValue) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
viewRequested = newValue;
|
||||
if (mediaRouteActionProvider != null) {
|
||||
mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setConnected(boolean newValue) {
|
||||
if (connected != newValue && resumed && prefEnabled && !prefEnabled) {
|
||||
if (newValue) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
connected = newValue;
|
||||
if (mediaRouteActionProvider != null) {
|
||||
mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean shouldEnable() {
|
||||
return prefEnabled && viewRequested;
|
||||
}
|
||||
|
||||
public void setMenu(Menu menu) {
|
||||
setViewRequested(false);
|
||||
showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM;
|
||||
this.menu = menu;
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
public void requestCastButton(int showAsAction) {
|
||||
setViewRequested(true);
|
||||
this.showAsAction = showAsAction;
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
public void onConnected() {
|
||||
setConnected(true);
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
public void onDisconnected() {
|
||||
setConnected(false);
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
private void setShowAsAction() {
|
||||
if (menu == null) {
|
||||
Log.d(TAG, "setShowAsAction() without a menu");
|
||||
return;
|
||||
}
|
||||
MenuItem item = menu.findItem(R.id.media_route_menu_item);
|
||||
if (item == null) {
|
||||
Log.e(TAG, "setShowAsAction(), but cast button not inflated");
|
||||
return;
|
||||
}
|
||||
MenuItemCompat.setShowAsAction(item, connected? MenuItem.SHOW_AS_ACTION_ALWAYS : showAsAction);
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
package de.danoeh.antennapod.core.cast;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
|
||||
public class CastButtonVisibilityManager {
|
||||
private static final String TAG = "CastBtnVisibilityMgr";
|
||||
private final CastManager castManager;
|
||||
private volatile boolean prefEnabled = false;
|
||||
private volatile boolean viewRequested = false;
|
||||
private volatile boolean resumed = false;
|
||||
private volatile boolean connected = false;
|
||||
private volatile int showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM;
|
||||
private Menu menu;
|
||||
public SwitchableMediaRouteActionProvider mediaRouteActionProvider;
|
||||
|
||||
public CastButtonVisibilityManager(CastManager castManager) {
|
||||
this.castManager = castManager;
|
||||
}
|
||||
|
||||
public synchronized void setPrefEnabled(boolean newValue) {
|
||||
if (prefEnabled != newValue && resumed && (viewRequested || connected)) {
|
||||
if (newValue) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
prefEnabled = newValue;
|
||||
if (mediaRouteActionProvider != null) {
|
||||
mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setResumed(boolean newValue) {
|
||||
if (resumed == newValue) {
|
||||
Log.e(TAG, "resumed should never change to the same value");
|
||||
return;
|
||||
}
|
||||
resumed = newValue;
|
||||
if (prefEnabled && (viewRequested || connected)) {
|
||||
if (resumed) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setViewRequested(boolean newValue) {
|
||||
if (viewRequested != newValue && resumed && prefEnabled && !connected) {
|
||||
if (newValue) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
viewRequested = newValue;
|
||||
if (mediaRouteActionProvider != null) {
|
||||
mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setConnected(boolean newValue) {
|
||||
if (connected != newValue && resumed && prefEnabled && !prefEnabled) {
|
||||
if (newValue) {
|
||||
castManager.incrementUiCounter();
|
||||
} else {
|
||||
castManager.decrementUiCounter();
|
||||
}
|
||||
}
|
||||
connected = newValue;
|
||||
if (mediaRouteActionProvider != null) {
|
||||
mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean shouldEnable() {
|
||||
return prefEnabled && viewRequested;
|
||||
}
|
||||
|
||||
public void setMenu(Menu menu) {
|
||||
setViewRequested(false);
|
||||
showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM;
|
||||
this.menu = menu;
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
public void requestCastButton(int showAsAction) {
|
||||
setViewRequested(true);
|
||||
this.showAsAction = showAsAction;
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
public void onConnected() {
|
||||
setConnected(true);
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
public void onDisconnected() {
|
||||
setConnected(false);
|
||||
setShowAsAction();
|
||||
}
|
||||
|
||||
private void setShowAsAction() {
|
||||
if (menu == null) {
|
||||
Log.d(TAG, "setShowAsAction() without a menu");
|
||||
return;
|
||||
}
|
||||
MenuItem item = menu.findItem(R.id.media_route_menu_item);
|
||||
if (item == null) {
|
||||
Log.e(TAG, "setShowAsAction(), but cast button not inflated");
|
||||
return;
|
||||
}
|
||||
MenuItemCompat.setShowAsAction(item, connected ? MenuItem.SHOW_AS_ACTION_ALWAYS : showAsAction);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue