Merge pull request #4347 from avently/player-rebind

Player rebind
This commit is contained in:
Tobias Groza 2020-10-01 15:03:43 +02:00 committed by GitHub
commit 4e7632949d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 98 additions and 23 deletions

View File

@ -20,7 +20,10 @@
package org.schabi.newpipe;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
@ -101,6 +104,8 @@ public class MainActivity extends AppCompatActivity {
private boolean servicesShown = false;
private ImageView serviceArrow;
private BroadcastReceiver broadcastReceiver;
private static final int ITEM_ID_SUBSCRIPTIONS = -1;
private static final int ITEM_ID_FEED = -2;
private static final int ITEM_ID_BOOKMARKS = -3;
@ -147,6 +152,7 @@ public class MainActivity extends AppCompatActivity {
if (DeviceUtils.isTv(this)) {
FocusOverlayView.setupFocusObserver(this);
}
setupBroadcastReceiver();
}
private void setupDrawer() throws Exception {
@ -454,6 +460,9 @@ public class MainActivity extends AppCompatActivity {
if (!isChangingConfigurations()) {
StateSaver.clearStateFiles();
}
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
}
}
@Override
@ -795,9 +804,36 @@ public class MainActivity extends AppCompatActivity {
ErrorActivity.reportUiError(this, e);
}
}
/*
* Utils
* */
private void setupBroadcastReceiver() {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(VideoDetailFragment.ACTION_PLAYER_STARTED)) {
final Fragment fragmentPlayer = getSupportFragmentManager()
.findFragmentById(R.id.fragment_player_holder);
if (fragmentPlayer == null) {
/*
* We still don't have a fragment attached to the activity.
* It can happen when a user started popup or background players
* without opening a stream inside the fragment.
* Adding it in a collapsed state (only mini player will be visible)
* */
NavigationHelper.showMiniPlayer(getSupportFragmentManager());
}
/*
* At this point the player is added 100%, we can unregister.
* Other actions are useless since the fragment will not be removed after that
* */
unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
}
}
};
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED);
registerReceiver(broadcastReceiver, intentFilter);
}
private boolean bottomSheetHiddenOrCollapsed() {
final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder);

View File

@ -146,6 +146,8 @@ public class VideoDetailFragment
"org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER";
public static final String ACTION_HIDE_MAIN_PLAYER =
"org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER";
public static final String ACTION_PLAYER_STARTED =
"org.schabi.newpipe.VideoDetailFragment.ACTION_PLAYER_STARTED";
public static final String ACTION_VIDEO_FRAGMENT_RESUMED =
"org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED";
public static final String ACTION_VIDEO_FRAGMENT_STOPPED =
@ -302,6 +304,12 @@ public class VideoDetailFragment
return instance;
}
public static VideoDetailFragment getInstanceInCollapsedState() {
final VideoDetailFragment instance = new VideoDetailFragment();
instance.bottomSheetState = BottomSheetBehavior.STATE_COLLAPSED;
return instance;
}
/*//////////////////////////////////////////////////////////////////////////
// Fragment's Lifecycle
@ -518,7 +526,7 @@ public class VideoDetailFragment
openVideoPlayer();
}
setOverlayPlayPauseImage();
setOverlayPlayPauseImage(player != null && player.isPlaying());
break;
case R.id.overlay_close_button:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
@ -1325,12 +1333,22 @@ public class VideoDetailFragment
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
} else if (intent.getAction().equals(ACTION_HIDE_MAIN_PLAYER)) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
} else if (intent.getAction().equals(ACTION_PLAYER_STARTED)) {
// If the state is not hidden we don't need to show the mini player
if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
// Rebound to the service if it was closed via notification or mini player
if (!PlayerHolder.bound) {
PlayerHolder.startService(App.getApp(), false, VideoDetailFragment.this);
}
}
}
};
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_SHOW_MAIN_PLAYER);
intentFilter.addAction(ACTION_HIDE_MAIN_PLAYER);
intentFilter.addAction(ACTION_PLAYER_STARTED);
activity.registerReceiver(broadcastReceiver, intentFilter);
}
@ -1719,8 +1737,12 @@ public class VideoDetailFragment
// It will allow to have live instance of PlayQueue with actual information about
// deleted/added items inside Channel/Playlist queue and makes possible to have
// a history of played items
if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue)) {
stack.push(new StackItem(serviceId, url, name, playQueue));
if ((stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue)
&& queue.getItem() != null)) {
stack.push(new StackItem(queue.getItem().getServiceId(),
queue.getItem().getUrl(),
queue.getItem().getTitle(),
queue));
} else {
final StackItem stackWithQueue = findQueueInStack(queue);
if (stackWithQueue != null) {
@ -1744,7 +1766,7 @@ public class VideoDetailFragment
final int repeatMode,
final boolean shuffled,
final PlaybackParameters parameters) {
setOverlayPlayPauseImage();
setOverlayPlayPauseImage(player != null && player.isPlaying());
switch (state) {
case BasePlayer.STATE_PLAYING:
@ -1818,7 +1840,7 @@ public class VideoDetailFragment
@Override
public void onServiceStopped() {
setOverlayPlayPauseImage();
setOverlayPlayPauseImage(false);
if (currentInfo != null) {
updateOverlayData(currentInfo.getName(),
currentInfo.getUploaderName(),
@ -2224,6 +2246,9 @@ public class VideoDetailFragment
break;
case BottomSheetBehavior.STATE_COLLAPSED:
moveFocusToMainFragment(true);
manageSpaceAtTheBottom(false);
bottomSheetBehavior.setPeekHeight(peekHeight);
// Re-enable clicks
setOverlayElementsClickable(true);
@ -2270,8 +2295,8 @@ public class VideoDetailFragment
}
}
private void setOverlayPlayPauseImage() {
final int attr = player != null && player.isPlaying()
private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {
final int attr = playerIsPlaying
? R.attr.ic_pause
: R.attr.ic_play_arrow;
overlayPlayPauseButton.setImageResource(

View File

@ -255,9 +255,9 @@ public class VideoPlayerImpl extends VideoPlayer
onQueueClosed();
// Android TV: without it focus will frame the whole player
playPauseButton.requestFocus();
onPlay();
}
onPlay();
NavigationHelper.sendPlayerStartedEvent(service);
}
VideoPlayerImpl(final MainPlayer service) {
@ -662,6 +662,7 @@ public class VideoPlayerImpl extends VideoPlayer
@Override
public void onPlayQueueEdited() {
updatePlayback();
showOrHideButtons();
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
}
@ -1455,15 +1456,16 @@ public class VideoPlayerImpl extends VideoPlayer
return;
}
playPreviousButton.setVisibility(playQueue.getIndex() == 0
? View.INVISIBLE
: View.VISIBLE);
playNextButton.setVisibility(playQueue.getIndex() + 1 == playQueue.getStreams().size()
? View.INVISIBLE
: View.VISIBLE);
queueButton.setVisibility(playQueue.getStreams().size() <= 1 || popupPlayerSelected()
? View.GONE
: View.VISIBLE);
final boolean showPrev = playQueue.getIndex() != 0;
final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size();
final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected();
playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE);
playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f);
playNextButton.setVisibility(showNext ? View.VISIBLE : View.INVISIBLE);
playNextButton.setAlpha(showNext ? 1.0f : 0.0f);
queueButton.setVisibility(showQueue ? View.VISIBLE : View.GONE);
queueButton.setAlpha(showQueue ? 1.0f : 0.0f);
}
private void showSystemUIPartially() {
@ -1936,6 +1938,7 @@ public class VideoPlayerImpl extends VideoPlayer
getControlsRoot().setPadding(0, 0, 0, 0);
}
queueLayout.setPadding(0, 0, 0, 0);
updateQueue();
updateMetadata();
updatePlayback();
triggerProgressUpdate();

View File

@ -384,8 +384,19 @@ public final class NavigationHelper {
}
public static void expandMainPlayer(final Context context) {
final Intent intent = new Intent(VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER);
context.sendBroadcast(intent);
context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER));
}
public static void sendPlayerStartedEvent(final Context context) {
context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_PLAYER_STARTED));
}
public static void showMiniPlayer(final FragmentManager fragmentManager) {
final VideoDetailFragment instance = VideoDetailFragment.getInstanceInCollapsedState();
defaultTransaction(fragmentManager)
.replace(R.id.fragment_player_holder, instance)
.runOnCommit(() -> sendPlayerStartedEvent(instance.requireActivity()))
.commit();
}
public static void openChannelFragment(final FragmentManager fragmentManager,