From 02a624075ad349b3a89e54dd02de1032c88c55c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 30 Mar 2026 10:31:52 -0600 Subject: [PATCH] Android: Make the "Auto" rotation mode override user rotation lock (SENSOR mode) --- Common/GPU/Vulkan/VulkanQueueRunner.cpp | 2 +- android/AndroidManifest.xml | 1 - .../src/org/ppsspp/ppsspp/PpssppActivity.java | 40 ++++++++++++------- .../src/org/ppsspp/ppsspp/SizeManager.java | 3 +- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index 81e683121b..93afd39957 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -8,7 +8,7 @@ using namespace PPSSPP_VK; -// Debug help: adb logcat -s DEBUG AndroidRuntime PPSSPPNativeActivity PPSSPP NativeGLView NativeRenderer NativeSurfaceView PowerSaveModeReceiver InputDeviceState PpssppActivity CameraHelper +// Debug help: adb logcat -s DEBUG AndroidRuntime PPSSPPNativeActivity PPSSPP NativeGLView NativeRenderer NativeSurfaceView PowerSaveModeReceiver InputDeviceState PpssppActivity CameraHelper PPSSPPSizeManager static void MergeRenderAreaRectInto(VkRect2D *dest, const VkRect2D &src) { if (dest->offset.x > src.offset.x) { diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 734519bc3b..7b886cd2c4 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -56,7 +56,6 @@ android:theme="@style/ppsspp_style" android:launchMode="singleInstance" android:exported="true"> - diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index 5e638f5e2c..637679551e 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -47,7 +47,6 @@ import android.view.Surface; import android.view.SurfaceView; import android.view.View; import android.view.Window; -import android.view.WindowInsets; import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; @@ -195,7 +194,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList try { optimalFramesPerBuffer = Integer.parseInt(this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); } catch (NumberFormatException e) { - // Ignore, if we can't parse it it's bogus and zero is a fine value (means we couldn't detect it). + // Ignore, if we can't parse it, it's bogus and zero is a fine value (means we couldn't detect it). } try { optimalSampleRate = Integer.parseInt(this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); @@ -576,6 +575,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (isInMultiWindowMode()) { // Do not try to enforce rotation! This can result in re-init loops. + Log.e(TAG, "Multi window mode, not setting orientation"); return; } } @@ -589,28 +589,37 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList Log.e(TAG, "Invalid rotation: " + rotString); return; } - Log.i(TAG, "Setting requested rotation: " + rot + " ('" + rotString + "') (" + cause + ")"); + // WARNING: when adding new modes here, check SizeManager's workaround in surfaceCreated.j + + int nativeRotation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; switch (rot) { case 0: - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + nativeRotation = ActivityInfo.SCREEN_ORIENTATION_SENSOR; break; case 1: - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + nativeRotation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case 2: - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + nativeRotation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case 3: - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); + nativeRotation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; case 4: - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); + nativeRotation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; case 5: - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + nativeRotation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; break; } + + if (getRequestedOrientation() != nativeRotation) { + Log.i(TAG, "Changing requested rotation to " + rot + " ('" + rotString + "') (" + cause + ")"); + setRequestedOrientation(nativeRotation); + } else { + Log.i(TAG, "Rotation already set."); + } } private boolean useImmersive() { @@ -775,7 +784,8 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList sizeManager.setSurfaceView(mSurfaceView); setInsetsListener(mSurfaceView); setContentView(mSurfaceView); - startRenderLoopThread(); + + // render loop thread will be started once we get a surface. } if (shortcutParam != null && !shortcutParam.isEmpty()) { @@ -922,12 +932,11 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList } public void notifySurface(Surface surface) { - Log.i(TAG, "notifySurface begin"); mSurface = surface; if (!javaGL) { if (!initialized) { - Log.e(TAG, "notifySurface end: Saving surface, but can't start/stop threads while not initialized"); + Log.e(TAG, "notifySurface: Saving surface, but can't start/stop threads while not initialized"); return; } @@ -935,16 +944,17 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList // NOTE: We do not try to join the thread here if (mSurface != null) { // applyFramerate is called in here. + Log.i(TAG, "notifySurface: got surface, starting thread."); startRenderLoopThread(); } else { - Log.i(TAG, "Notified surface is null, not starting thread."); + Log.i(TAG, "notifySurface: Notified surface is null, not starting thread."); } } else if (mSurface != null) { // JavaGL path. + Log.i(TAG, "notifySurface: Applying framerate."); applyFrameRate(mSurface, 60.0f); } updateSustainedPerformanceMode(); - Log.i(TAG, "notifySurface end"); } // The render loop thread (EmuThread) is now spawned from the native side. @@ -1125,8 +1135,8 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { - Log.i(TAG, "onConfigurationChanged"); super.onConfigurationChanged(newConfig); + Log.i(TAG, "onConfigurationChanged"); updateSystemUiVisibility(); sizeManager.updateDpi((float)newConfig.densityDpi); } diff --git a/android/src/org/ppsspp/ppsspp/SizeManager.java b/android/src/org/ppsspp/ppsspp/SizeManager.java index 2f1507ed8e..915a334f5a 100644 --- a/android/src/org/ppsspp/ppsspp/SizeManager.java +++ b/android/src/org/ppsspp/ppsspp/SizeManager.java @@ -63,10 +63,11 @@ public class SizeManager implements SurfaceHolder.Callback { int pixelHeight = holder.getSurfaceFrame().height(); // Workaround for terrible bug when locking and unlocking the screen in landscape mode on Nexus 5X. + // TODO: Look into removing this. int requestedOr = activity.getRequestedOrientation(); boolean requestedPortrait = requestedOr == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || requestedOr == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; boolean detectedPortrait = pixelHeight > pixelWidth; - if (badOrientationCount < 3 && requestedPortrait != detectedPortrait && requestedOr != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { + if (badOrientationCount < 3 && requestedPortrait != detectedPortrait && requestedOr != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED && requestedOr != ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE && requestedOr != ActivityInfo.SCREEN_ORIENTATION_SENSOR) { Log.e(TAG, "Bad orientation detected (w=" + pixelWidth + " h=" + pixelHeight + "! Recreating activity."); badOrientationCount++; activity.recreate();