From 92ff98d99ac0146db45c5f2cd1b4ebc7716c07a6 Mon Sep 17 00:00:00 2001 From: Avently <7953703+avently@users.noreply.github.com> Date: Thu, 16 Jan 2020 14:20:22 +0300 Subject: [PATCH] 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 --- .../fragments/detail/VideoDetailFragment.java | 61 ++++++++----------- .../org/schabi/newpipe/player/MainPlayer.java | 2 +- .../newpipe/player/VideoPlayerImpl.java | 41 ++++++++++++- .../event/PlayerServiceEventListener.java | 2 + .../newpipe/player/helper/PlayerHelper.java | 8 +++ .../settings/SettingsContentObserver.java | 29 --------- .../activity_main_player.xml | 15 +++++ .../main/res/layout/activity_main_player.xml | 15 +++++ 8 files changed, 106 insertions(+), 67 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/settings/SettingsContentObserver.java diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 5493d05cc..cfaf0aea4 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -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() { diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index b7081f71e..63c2f195f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -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; diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 2da110712..66407936c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -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)); } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java index 7422f9442..eeff08b5c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java @@ -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); diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index a0152c13a..cfce6e678 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -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 //////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsContentObserver.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsContentObserver.java deleted file mode 100644 index 534fb26c3..000000000 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsContentObserver.java +++ /dev/null @@ -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(); - } -} \ No newline at end of file diff --git a/app/src/main/res/layout-large-land/activity_main_player.xml b/app/src/main/res/layout-large-land/activity_main_player.xml index df0ada0b0..16a52cdb6 100644 --- a/app/src/main/res/layout-large-land/activity_main_player.xml +++ b/app/src/main/res/layout-large-land/activity_main_player.xml @@ -466,6 +466,21 @@ android:visibility="gone" android:background="?attr/selectableItemBackground" tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" /> + + diff --git a/app/src/main/res/layout/activity_main_player.xml b/app/src/main/res/layout/activity_main_player.xml index b00a3a4d4..1a0fb292f 100644 --- a/app/src/main/res/layout/activity_main_player.xml +++ b/app/src/main/res/layout/activity_main_player.xml @@ -464,6 +464,21 @@ android:visibility="gone" android:background="?attr/selectableItemBackground" tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" /> + +