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 9e9695725..72be11cc6 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 @@ -263,8 +263,10 @@ public void onServiceConnected(final Player connectedPlayer, // let's make the video in fullscreen again checkLandscape(); } else if (player.isFullscreen() && !player.isVerticalVideo() - // Tablet UI has orientation-independent fullscreen - && !DeviceUtils.isTablet(activity)) { + // Tablet UI has orientation-independent fullscreen, + // large screens can't be rotated programmatically anyway + && !DeviceUtils.isTablet(activity) + && !DeviceUtils.isOrientationRequestIgnored(activity)) { // Device is in portrait orientation after rotation but UI is in fullscreen. // Return back to non-fullscreen state player.toggleFullscreen(); @@ -2286,13 +2288,17 @@ public void onScreenRotationButtonClicked() { final boolean isTablet = DeviceUtils.isTablet(activity); final boolean autoLocked = globalScreenOrientationLocked(activity); - // 1. 平板且(系统可自动旋转 或 当前已横),直接切播放器全屏/非全屏 - if (isTablet && (!autoLocked || isLandscape)) { + // 1. Tablet with auto-rotate enabled (or already in landscape): toggle player + // fullscreen directly. On large screens (sw >= 600dp, e.g. unfolded foldables) + // the system ignores setRequestedOrientation(), so rotating programmatically + // is impossible — toggle fullscreen directly there as well + if (isTablet && (!autoLocked || isLandscape) + || DeviceUtils.isOrientationRequestIgnored(requireContext())) { player.toggleFullscreen(); return; } - // 2. 手机 or 平板但系统锁定了自动旋转,就去真正设置屏幕方向 + // 2. Phone (or tablet with auto-rotate locked): actually change screen orientation if (!autoLocked) { if (isLandscape) { player.toggleFullscreen(); @@ -2300,7 +2306,7 @@ public void onScreenRotationButtonClicked() { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } } else { - // 系统锁定时,再用“强制模式”来切 + // Auto-rotate is locked, force the orientation change activity.setRequestedOrientation( isLandscape ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index e8b1f6da3..bf9a10f7e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -5002,6 +5002,9 @@ public void onVideoSizeChanged(@NonNull final VideoSize videoSize) { && service.isLandscape() == isVerticalVideo && !DeviceUtils.isTv(context) && !DeviceUtils.isTablet(context) + // can't rotate large screens programmatically, and with the + // fallback to toggleFullscreen() this would exit fullscreen + && !DeviceUtils.isOrientationRequestIgnored(context) && fragmentListener != null) { // set correct orientation fragmentListener.onScreenRotationButtonClicked(); diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index d6bd77e1c..3e4f422ca 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -170,6 +170,19 @@ public static boolean isTablet(@NonNull final Context context) { & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; } + /** + * Whether the system ignores {@link android.app.Activity#setRequestedOrientation(int)}. + * + *

Since Android 12L, devices with a display at least 600dp wide (tablets, unfolded + * foldables) may ignore fixed-orientation requests; since Android 16 with targetSdk 36 + * this is guaranteed. On such screens fullscreen has to be toggled without trying to + * change the screen orientation.

+ */ + public static boolean isOrientationRequestIgnored(@NonNull final Context context) { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2 + && context.getResources().getConfiguration().smallestScreenWidthDp >= 600; + } + public static boolean isConfirmKey(final int keyCode) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: