Skip to content

Commit

Permalink
-Removed system ui on main player for Kitkat or above.
Browse files Browse the repository at this point in the history
-[#1151] Hide video player UI on playing to avoid unnecessary interruptions after pause, seek and resize.
  • Loading branch information
karyogamy committed Mar 1, 2018
1 parent 9ea08c8 commit 49c620b
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 63 deletions.
6 changes: 2 additions & 4 deletions app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
Expand Up @@ -425,15 +425,13 @@ public void onPlaying() {
if (!isProgressLoopRunning()) startProgressLoop();
}

public void onBuffering() {
}
public void onBuffering() {}

public void onPaused() {
if (isProgressLoopRunning()) stopProgressLoop();
}

public void onPausedSeek() {
}
public void onPausedSeek() {}

public void onCompleted() {
if (DEBUG) Log.d(TAG, "onCompleted() called");
Expand Down
114 changes: 76 additions & 38 deletions app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
Expand Up @@ -69,6 +69,9 @@

import java.util.List;

import static org.schabi.newpipe.player.BasePlayer.STATE_PLAYING;
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_DURATION;
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME;
import static org.schabi.newpipe.util.AnimationUtils.animateView;

/**
Expand Down Expand Up @@ -114,7 +117,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
return;
}

showSystemUi();
changeSystemUi();
setContentView(R.layout.activity_main_player);
playerImpl = new VideoPlayerImpl(this);
playerImpl.setup(findViewById(android.R.id.content));
Expand Down Expand Up @@ -206,31 +209,53 @@ public void onConfigurationChanged(Configuration newConfig) {
// Utils
//////////////////////////////////////////////////////////////////////////*/

/**
* Prior to Kitkat, hiding system ui causes the player view to be overlaid and require two
* clicks to get rid of that invisible overlay. By showing the system UI on actions/events,
* that overlay is removed and the player view is put to the foreground.
*
* Post Kitkat, navbar and status bar can be pulled out by swiping the edge of
* screen, therefore, we can do nothing or hide the UI on actions/events.
* */
private void changeSystemUi() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
showSystemUi();
} else {
hideSystemUi();
}
}

private void showSystemUi() {
if (DEBUG) Log.d(TAG, "showSystemUi() called");
if (playerImpl != null && playerImpl.queueVisible) return;

final int visibility;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
} else getWindow().getDecorView().setSystemUiVisibility(0);
visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
} else {
visibility = View.STATUS_BAR_VISIBLE;
}
getWindow().getDecorView().setSystemUiVisibility(visibility);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}

private void hideSystemUi() {
if (DEBUG) Log.d(TAG, "hideSystemUi() called");
if (android.os.Build.VERSION.SDK_INT >= 16) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) visibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
visibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
getWindow().getDecorView().setSystemUiVisibility(visibility);
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}

private void toggleOrientation() {
Expand Down Expand Up @@ -307,6 +332,7 @@ private class VideoPlayerImpl extends VideoPlayer {
private ImageButton switchPopupButton;
private ImageButton switchBackgroundButton;

private RelativeLayout windowRootLayout;
private View secondaryControls;

VideoPlayerImpl(final Context context) {
Expand Down Expand Up @@ -334,6 +360,19 @@ public void initViews(View rootView) {
this.switchBackgroundButton = rootView.findViewById(R.id.switchBackground);
this.switchPopupButton = rootView.findViewById(R.id.switchPopup);

this.queueLayout = findViewById(R.id.playQueuePanel);
this.itemsListCloseButton = findViewById(R.id.playQueueClose);
this.itemsList = findViewById(R.id.playQueue);

this.windowRootLayout = rootView.findViewById(R.id.playbackWindowRoot);
// Prior to Kitkat, there is no way of setting translucent navbar programmatically.
// Thus, fit system windows is opted instead.
// See https://stackoverflow.com/questions/29069070/completely-transparent-status-bar-and-navigation-bar-on-lollipop
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
windowRootLayout.setFitsSystemWindows(false);
windowRootLayout.invalidate();
}

titleTextView.setSelected(true);
channelTextView.setSelected(true);

Expand Down Expand Up @@ -508,9 +547,9 @@ public void onClick(View v) {

if (getCurrentState() != STATE_COMPLETED) {
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
animateView(getControlsRoot(), true, 300, 0, () -> {
animateView(getControlsRoot(), true, DEFAULT_CONTROLS_DURATION, 0, () -> {
if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) {
hideControls(300, DEFAULT_CONTROLS_HIDE_TIME);
hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
}
});
}
Expand Down Expand Up @@ -546,7 +585,7 @@ private void onMoreOptionsClicked() {
R.drawable.ic_expand_less_white_24dp));
animateView(secondaryControls, true, 200);
}
showControls(300);
showControls(DEFAULT_CONTROLS_DURATION);
}

private void onScreenRotationClicked() {
Expand All @@ -558,15 +597,13 @@ private void onScreenRotationClicked() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
super.onStopTrackingTouch(seekBar);
if (wasPlaying()) {
hideControls(100, 0);
}
if (wasPlaying()) showControlsThenHide();
}

@Override
public void onDismiss(PopupMenu menu) {
super.onDismiss(menu);
if (isPlaying()) hideControls(300, 0);
if (isPlaying()) hideControls(DEFAULT_CONTROLS_DURATION, 0);
}

@Override
Expand Down Expand Up @@ -624,7 +661,8 @@ public void onPlaying() {
playPauseButton.setImageResource(R.drawable.ic_pause_white);
animatePlayButtons(true, 200);
});
showSystemUi();

changeSystemUi();
getRootView().setKeepScreenOn(true);
}

Expand All @@ -636,7 +674,7 @@ public void onPaused() {
animatePlayButtons(true, 200);
});

showSystemUi();
changeSystemUi();
getRootView().setKeepScreenOn(false);
}

Expand All @@ -650,10 +688,9 @@ public void onPausedSeek() {

@Override
public void onCompleted() {
showSystemUi();
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, () -> {
playPauseButton.setImageResource(R.drawable.ic_replay_white);
animatePlayButtons(true, 300);
animatePlayButtons(true, DEFAULT_CONTROLS_DURATION);
});

getRootView().setKeepScreenOn(false);
Expand Down Expand Up @@ -683,8 +720,9 @@ public void hideControls(final long duration, long delay) {
if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]");
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
getControlsVisibilityHandler().postDelayed(() ->
animateView(getControlsRoot(), false, duration, 0, MainVideoPlayer.this::hideSystemUi),
delay
animateView(getControlsRoot(), false, duration, 0,
MainVideoPlayer.this::hideSystemUi),
/*delayMillis=*/delay
);
}

Expand All @@ -697,11 +735,6 @@ private void updatePlaybackButtons() {
}

private void buildQueue() {
queueLayout = findViewById(R.id.playQueuePanel);

itemsListCloseButton = findViewById(R.id.playQueueClose);

itemsList = findViewById(R.id.playQueue);
itemsList.setAdapter(playQueueAdapter);
itemsList.setClickable(true);
itemsList.setLongClickable(true);
Expand Down Expand Up @@ -830,10 +863,11 @@ public boolean onSingleTapConfirmed(MotionEvent e) {
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
if (playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED) return true;

if (playerImpl.isControlsVisible()) playerImpl.hideControls(150, 0);
else {
if (playerImpl.isControlsVisible()) {
playerImpl.hideControls(150, 0);
} else {
playerImpl.showControlsThenHide();
showSystemUi();
changeSystemUi();
}
return true;
}
Expand Down Expand Up @@ -916,11 +950,15 @@ private void onScrollEnd() {
eventsNum = 0;
/* if (playerImpl.getVolumeTextView().getVisibility() == View.VISIBLE) playerImpl.getVolumeTextView().setVisibility(View.GONE);
if (playerImpl.getBrightnessTextView().getVisibility() == View.VISIBLE) playerImpl.getBrightnessTextView().setVisibility(View.GONE);*/
if (playerImpl.getVolumeTextView().getVisibility() == View.VISIBLE) animateView(playerImpl.getVolumeTextView(), false, 200, 200);
if (playerImpl.getBrightnessTextView().getVisibility() == View.VISIBLE) animateView(playerImpl.getBrightnessTextView(), false, 200, 200);
if (playerImpl.getVolumeTextView().getVisibility() == View.VISIBLE) {
animateView(playerImpl.getVolumeTextView(), false, 200, 200);
}
if (playerImpl.getBrightnessTextView().getVisibility() == View.VISIBLE) {
animateView(playerImpl.getBrightnessTextView(), false, 200, 200);
}

if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == BasePlayer.STATE_PLAYING) {
playerImpl.hideControls(300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME);
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
}
}

Expand Down
Expand Up @@ -70,6 +70,9 @@

import java.util.List;

import static org.schabi.newpipe.player.BasePlayer.STATE_PLAYING;
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_DURATION;
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME;
import static org.schabi.newpipe.player.helper.PlayerHelper.isUsingOldPlayer;
import static org.schabi.newpipe.util.AnimationUtils.animateView;

Expand Down Expand Up @@ -646,6 +649,8 @@ public void onPlaying() {
super.onPlaying();
updateNotification(R.drawable.ic_pause_white);
lockManager.acquireWifiAndCpu();

hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
}

@Override
Expand Down Expand Up @@ -778,8 +783,8 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float d
private void onScrollEnd() {
if (DEBUG) Log.d(TAG, "onScrollEnd() called");
if (playerImpl == null) return;
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == BasePlayer.STATE_PLAYING) {
playerImpl.hideControls(300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME);
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
}
}

Expand Down
32 changes: 13 additions & 19 deletions app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java
Expand Up @@ -101,6 +101,7 @@ public abstract class VideoPlayer extends BasePlayer
//////////////////////////////////////////////////////////////////////////*/

protected static final int RENDERER_UNAVAILABLE = -1;
public static final int DEFAULT_CONTROLS_DURATION = 300; // 300 millis
public static final int DEFAULT_CONTROLS_HIDE_TIME = 2000; // 2 Seconds

private ArrayList<VideoStream> availableStreams;
Expand Down Expand Up @@ -450,7 +451,7 @@ public void onBlocked() {
super.onBlocked();

controlsVisibilityHandler.removeCallbacksAndMessages(null);
animateView(controlsRoot, false, 300);
animateView(controlsRoot, false, DEFAULT_CONTROLS_DURATION);

playbackSeekBar.setEnabled(false);
// Bug on lower api, disabling and enabling the seekBar resets the thumb color -.-, so sets the color again
Expand All @@ -475,7 +476,7 @@ public void onPlaying() {
playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);

loadingPanel.setVisibility(View.GONE);
showControlsThenHide();

animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200);
animateView(endScreen, false, 0);
}
Expand Down Expand Up @@ -707,7 +708,7 @@ public void onQualitySelectorClicked() {
if (DEBUG) Log.d(TAG, "onQualitySelectorClicked() called");
qualityPopupMenu.show();
isSomePopupMenuVisible = true;
showControls(300);
showControls(DEFAULT_CONTROLS_DURATION);

final VideoStream videoStream = getSelectedVideoStream();
if (videoStream != null) {
Expand All @@ -723,14 +724,14 @@ private void onPlaybackSpeedClicked() {
if (DEBUG) Log.d(TAG, "onPlaybackSpeedClicked() called");
playbackSpeedPopupMenu.show();
isSomePopupMenuVisible = true;
showControls(300);
showControls(DEFAULT_CONTROLS_DURATION);
}

private void onCaptionClicked() {
if (DEBUG) Log.d(TAG, "onCaptionClicked() called");
captionPopupMenu.show();
isSomePopupMenuVisible = true;
showControls(300);
showControls(DEFAULT_CONTROLS_DURATION);
}

private void onResizeClicked() {
Expand Down Expand Up @@ -763,7 +764,8 @@ public void onStartTrackingTouch(SeekBar seekBar) {
if (isPlaying()) simpleExoPlayer.setPlayWhenReady(false);

showControls(0);
animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, true, 300);
animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, true,
DEFAULT_CONTROLS_DURATION);
}

@Override
Expand Down Expand Up @@ -819,7 +821,7 @@ public void showAndAnimateControl(final int drawableId, final boolean goneOnEnd)
PropertyValuesHolder.ofFloat(View.ALPHA, 1f, 0f),
PropertyValuesHolder.ofFloat(View.SCALE_X, 1.4f, 1f),
PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.4f, 1f)
).setDuration(300);
).setDuration(DEFAULT_CONTROLS_DURATION);
controlViewAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Expand Down Expand Up @@ -861,12 +863,8 @@ public boolean isSomePopupMenuVisible() {

public void showControlsThenHide() {
if (DEBUG) Log.d(TAG, "showControlsThenHide() called");
animateView(controlsRoot, true, 300, 0, new Runnable() {
@Override
public void run() {
hideControls(300, DEFAULT_CONTROLS_HIDE_TIME);
}
});
animateView(controlsRoot, true, DEFAULT_CONTROLS_DURATION, 0,
() -> hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME));
}

public void showControls(long duration) {
Expand All @@ -878,12 +876,8 @@ public void showControls(long duration) {
public void hideControls(final long duration, long delay) {
if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]");
controlsVisibilityHandler.removeCallbacksAndMessages(null);
controlsVisibilityHandler.postDelayed(new Runnable() {
@Override
public void run() {
animateView(controlsRoot, false, duration);
}
}, delay);
controlsVisibilityHandler.postDelayed(
() -> animateView(controlsRoot, false, duration), delay);
}

/*//////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_main_player.xml
Expand Up @@ -134,6 +134,7 @@
tools:visibility="visible">

<RelativeLayout
android:id="@+id/playbackWindowRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
Expand Down

0 comments on commit 49c620b

Please sign in to comment.