New logic for handling global orientation

- added a button to manually change an orientation of a video
- adapted UI for an automatic global orientation too
This commit is contained in:
Avently 2020-01-16 14:20:22 +03:00
parent d1609cba90
commit 92ff98d99a
8 changed files with 106 additions and 67 deletions

View File

@ -4,6 +4,7 @@ import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.*;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.os.Build;
@ -69,7 +70,6 @@ import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.playqueue.*;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.settings.SettingsContentObserver;
import org.schabi.newpipe.util.*;
import org.schabi.newpipe.views.AnimatedProgressBar;
@ -97,8 +97,7 @@ public class VideoDetailFragment
View.OnClickListener,
View.OnLongClickListener,
PlayerEventListener,
PlayerServiceEventListener,
SettingsContentObserver.OnChangeListener {
PlayerServiceEventListener {
public static final String AUTO_PLAY = "auto_play";
private boolean isFragmentStopped;
@ -203,7 +202,7 @@ public class VideoDetailFragment
private TabLayout tabLayout;
private FrameLayout relatedStreamsLayout;
private SettingsContentObserver settingsContentObserver;
private ContentObserver settingsContentObserver;
private ServiceConnection serviceConnection;
private boolean bounded;
private MainPlayer playerService;
@ -329,9 +328,15 @@ public class VideoDetailFragment
startService(false);
setupBroadcastReceiver();
settingsContentObserver = new SettingsContentObserver(new Handler(), this);
settingsContentObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
if(activity != null && !PlayerHelper.globalScreenOrientationLocked(activity))
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
};
activity.getContentResolver().registerContentObserver(
android.provider.Settings.System.CONTENT_URI, true,
Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), false,
settingsContentObserver);
}
@ -1311,13 +1316,6 @@ public class VideoDetailFragment
// Orientation listener
//////////////////////////////////////////////////////////////////////////*/
private boolean globalScreenOrientationLocked() {
// 1: Screen orientation changes using accelerometer
// 0: Screen orientation is locked
return !(android.provider.Settings.System.getInt(
activity.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 1);
}
private void restoreDefaultOrientation() {
if (player == null || !player.videoPlayerSelected() || activity == null) return;
@ -1327,25 +1325,6 @@ public class VideoDetailFragment
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
private void setupOrientation() {
if (player == null || !player.videoPlayerSelected() || activity == null) return;
int newOrientation;
if (globalScreenOrientationLocked())
newOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
else
newOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
if (newOrientation != activity.getRequestedOrientation())
activity.setRequestedOrientation(newOrientation);
}
@Override
public void onSettingsChanged() {
if(activity != null && !globalScreenOrientationLocked())
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
/*//////////////////////////////////////////////////////////////////////////
// Contract
//////////////////////////////////////////////////////////////////////////*/
@ -1661,7 +1640,6 @@ public class VideoDetailFragment
animateView(positionView, true, 100);
animateView(detailPositionView, true, 100);
}
setupOrientation();
break;
}
}
@ -1742,6 +1720,15 @@ public class VideoDetailFragment
addVideoPlayerView();
}
@Override
public void onScreenRotationButtonClicked() {
int newOrientation = isLandscape() ?
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
: ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
activity.setRequestedOrientation(newOrientation);
}
/*
* Will scroll down to description view after long click on moreOptionsButton
* */
@ -1828,9 +1815,15 @@ public class VideoDetailFragment
if ((!player.isPlaying() && player.getPlayQueue() != playQueue) || player.getPlayQueue() == null)
setAutoplay(true);
boolean orientationLocked = PlayerHelper.globalScreenOrientationLocked(activity);
// Let's give a user time to look at video information page if video is not playing
if (player.isPlaying())
if (player.isPlaying()) {
player.checkLandscape();
} else if (orientationLocked) {
player.checkLandscape();
player.onPlay();
player.showControlsThenHide();
}
}
private boolean isLandscape() {

View File

@ -195,7 +195,7 @@ public final class MainPlayer extends Service {
boolean isLandscape() {
// DisplayMetrics from activity context knows about MultiWindow feature while DisplayMetrics from app context doesn't
final DisplayMetrics metrics = playerImpl.getParentActivity() != null ?
final DisplayMetrics metrics = playerImpl != null && playerImpl.getParentActivity() != null ?
playerImpl.getParentActivity().getResources().getDisplayMetrics()
: getResources().getDisplayMetrics();
return metrics.heightPixels < metrics.widthPixels;

View File

@ -23,12 +23,15 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.content.*;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@ -88,7 +91,7 @@ import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
public class VideoPlayerImpl extends VideoPlayer
implements View.OnLayoutChangeListener,
PlaybackParameterDialog.Callback,
View.OnLongClickListener{
View.OnLongClickListener {
private static final String TAG = ".VideoPlayerImpl";
private final float MAX_GESTURE_LENGTH = 0.75f;
@ -109,6 +112,7 @@ public class VideoPlayerImpl extends VideoPlayer
private ImageButton openInBrowser;
private ImageButton fullscreenButton;
private ImageButton playerCloseButton;
private ImageButton screenRotationButton;
private ImageButton playPauseButton;
private ImageButton playPreviousButton;
@ -139,6 +143,7 @@ public class VideoPlayerImpl extends VideoPlayer
private PlayerEventListener activityListener;
private GestureDetector gestureDetector;
private SharedPreferences defaultPreferences;
private ContentObserver settingsContentObserver;
@NonNull
final private AudioPlaybackResolver resolver;
@ -233,6 +238,7 @@ public class VideoPlayerImpl extends VideoPlayer
this.playWithKodi = rootView.findViewById(R.id.playWithKodi);
this.openInBrowser = rootView.findViewById(R.id.openInBrowser);
this.fullscreenButton = rootView.findViewById(R.id.fullScreenButton);
this.screenRotationButton = rootView.findViewById(R.id.screenRotationButton);
this.playerCloseButton = rootView.findViewById(R.id.playerCloseButton);
this.playPauseButton = rootView.findViewById(R.id.playPauseButton);
@ -277,6 +283,7 @@ public class VideoPlayerImpl extends VideoPlayer
private void setupElementsVisibility() {
if (popupPlayerSelected()) {
fullscreenButton.setVisibility(View.VISIBLE);
screenRotationButton.setVisibility(View.GONE);
getRootView().findViewById(R.id.spaceBeforeControls).setVisibility(View.GONE);
getRootView().findViewById(R.id.metadataView).setVisibility(View.GONE);
queueButton.setVisibility(View.GONE);
@ -292,6 +299,7 @@ public class VideoPlayerImpl extends VideoPlayer
playerCloseButton.setVisibility(View.GONE);
} else {
fullscreenButton.setVisibility(View.GONE);
setupScreenRotationButton(service.isLandscape());
getRootView().findViewById(R.id.spaceBeforeControls).setVisibility(View.VISIBLE);
getRootView().findViewById(R.id.metadataView).setVisibility(View.VISIBLE);
moreOptionsButton.setVisibility(View.VISIBLE);
@ -337,10 +345,19 @@ public class VideoPlayerImpl extends VideoPlayer
moreOptionsButton.setOnLongClickListener(this);
shareButton.setOnClickListener(this);
fullscreenButton.setOnClickListener(this);
screenRotationButton.setOnClickListener(this);
playWithKodi.setOnClickListener(this);
openInBrowser.setOnClickListener(this);
playerCloseButton.setOnClickListener(this);
settingsContentObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) { setupScreenRotationButton(service.isLandscape()); }
};
service.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), false,
settingsContentObserver);
getRootView().addOnLayoutChangeListener((view, l, t, r, b, ol, ot, or, ob) -> {
if (l != ol || t != ot || r != or || b != ob) {
// Use smaller value to be consistent between screen orientations
@ -560,6 +577,7 @@ public class VideoPlayerImpl extends VideoPlayer
channelTextView.setVisibility(View.VISIBLE);
playerCloseButton.setVisibility(View.GONE);
}
setupScreenRotationButton(isInFullscreen());
}
@Override
@ -598,6 +616,9 @@ public class VideoPlayerImpl extends VideoPlayer
} else if (v.getId() == fullscreenButton.getId()) {
toggleFullscreen();
} else if (v.getId() == screenRotationButton.getId()) {
fragmentListener.onScreenRotationButtonClicked();
} else if (v.getId() == playerCloseButton.getId()) {
service.sendBroadcast(new Intent(VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER));
}
@ -689,6 +710,13 @@ public class VideoPlayerImpl extends VideoPlayer
builder.create().show();
}
private void setupScreenRotationButton(boolean landscape) {
boolean orientationLocked = PlayerHelper.globalScreenOrientationLocked(service);
screenRotationButton.setVisibility(orientationLocked && videoPlayerSelected() ? View.VISIBLE : View.GONE);
screenRotationButton.setImageDrawable(service.getResources().getDrawable(
landscape ? R.drawable.ic_fullscreen_exit_white : R.drawable.ic_fullscreen_white));
}
@Override
public void onPlaybackSpeedClicked() {
if (videoPlayerSelected()) {
@ -880,6 +908,13 @@ public class VideoPlayerImpl extends VideoPlayer
super.onCompleted();
}
@Override
public void destroy() {
super.destroy();
service.getContentResolver().unregisterContentObserver(settingsContentObserver);
}
/*//////////////////////////////////////////////////////////////////////////
// Broadcast Receiver
//////////////////////////////////////////////////////////////////////////*/
@ -1282,7 +1317,7 @@ public class VideoPlayerImpl extends VideoPlayer
getLoadingPanel().setMinimumHeight(popupLayoutParams.height);
service.removeViewFromParent();
windowManager.addView(service.getView(), popupLayoutParams);
windowManager.addView(getRootView(), popupLayoutParams);
if (getAspectRatioFrameLayout().getResizeMode() == AspectRatioFrameLayout.RESIZE_MODE_ZOOM)
onResizeClicked();
@ -1313,7 +1348,7 @@ public class VideoPlayerImpl extends VideoPlayer
}
private void initVideoPlayer() {
service.getView().setLayoutParams(new FrameLayout.LayoutParams(
getRootView().setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
}

View File

@ -5,6 +5,8 @@ import com.google.android.exoplayer2.ExoPlaybackException;
public interface PlayerServiceEventListener extends PlayerEventListener {
void onFullscreenStateChanged(boolean fullscreen);
void onScreenRotationButtonClicked();
void onMoreOptionsLongClicked();
void onPlayerError(ExoPlaybackException error);

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.provider.Settings;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -321,6 +322,13 @@ public class PlayerHelper {
setScreenBrightness(context, setScreenBrightness, System.currentTimeMillis());
}
public static boolean globalScreenOrientationLocked(Context context) {
// 1: Screen orientation changes using accelerometer
// 0: Screen orientation is locked
return !(android.provider.Settings.System.getInt(
context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 1);
}
////////////////////////////////////////////////////////////////////////////
// Private helpers
////////////////////////////////////////////////////////////////////////////

View File

@ -1,29 +0,0 @@
package org.schabi.newpipe.settings;
import android.database.ContentObserver;
import android.os.Handler;
public class SettingsContentObserver extends ContentObserver {
private OnChangeListener listener;
public interface OnChangeListener {
void onSettingsChanged();
}
public SettingsContentObserver(Handler handler, OnChangeListener listener) {
super(handler);
this.listener = listener;
}
@Override
public boolean deliverSelfNotifications() {
return super.deliverSelfNotifications();
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (listener != null)
listener.onSettingsChanged();
}
}

View File

@ -466,6 +466,21 @@
android:visibility="gone"
android:background="?attr/selectableItemBackground"
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
<ImageButton
android:id="@+id/screenRotationButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="4dp"
android:padding="6dp"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_fullscreen_white"
tools:ignore="ContentDescription,RtlHardcoded"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
</RelativeLayout>

View File

@ -464,6 +464,21 @@
android:visibility="gone"
android:background="?attr/selectableItemBackground"
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
<ImageButton
android:id="@+id/screenRotationButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="4dp"
android:padding="6dp"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_fullscreen_white"
tools:ignore="ContentDescription,RtlHardcoded"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
</RelativeLayout>