Commit 6ee661398d94db9f6eac38b31269a3665432125a

Sam Lantinga 2017-08-13T20:55:59

Fixed bug 3235 - Make the Android window creation similar to iOS' window creation Sylvain Here's a patch. It tries to get the hint first. Resizable will allow any orientation. Otherwise it uses width/height window. setOrientation method is splitted in static and non-static, so that it can be overloaded in a user subclass. Some artefact observed : surfaceChanged() can be called twice at the beginning. When the phone starts in portrait and run a landscape application.

diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java
index 10c3454..1d8eb2c 100644
--- a/android-project/src/org/libsdl/app/SDLActivity.java
+++ b/android-project/src/org/libsdl/app/SDLActivity.java
@@ -515,6 +515,61 @@ public class SDLActivity extends Activity {
 
     /**
      * This method is called by SDL using JNI.
+     * This is a static method for JNI convenience, it calls a non-static method
+     * so that is can be overridden  
+     */
+    public static void setOrientation(int w, int h, boolean resizable, String hint)
+    {
+      mSingleton.setOrientationBis(w, h, resizable, hint);
+      return;
+    }
+   
+    /**
+     * This can be overridden
+     */
+    public void setOrientationBis(int w, int h, boolean resizable, String hint) 
+    {
+      int orientation = -1;
+
+      if (hint != "") {
+         if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) {
+            orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+         } else if (hint.contains("LandscapeRight")) {
+            orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+         } else if (hint.contains("LandscapeLeft")) {
+            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+         } else if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) {
+            orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+         } else if (hint.contains("Portrait")) {
+            orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+         } else if (hint.contains("PortraitUpsideDown")) {
+            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+         }
+      }
+
+      /* no valid hint */
+      if (orientation == -1) {
+         if (resizable) {
+            /* no fixed orientation */
+         } else {
+            if (w > h) {
+               orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+            } else {
+               orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+            }
+         }
+      }
+
+      Log.v("SDL", "setOrientation() orientation=" + orientation + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint);
+      if (orientation != -1) {
+         mSingleton.setRequestedOrientation(orientation);
+      }
+ 
+      return;
+    }
+
+    /**
+     * This method is called by SDL using JNI.
      */
     public static boolean sendMessage(int command, int param) {
         return mSingleton.sendCommand(command, Integer.valueOf(param));
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 9029254..1d7d159 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -636,6 +636,18 @@ void Android_JNI_SetActivityTitle(const char *title)
     }
 }
 
+void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint)
+{
+    jmethodID mid;
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+    mid = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,"setOrientation","(IIZLjava/lang/String;)V");
+    if (mid) {
+        jstring jhint = (jstring)((*mEnv)->NewStringUTF(mEnv, (hint ? hint : "")));
+        (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, mid, w, h, (resizable? 1 : 0), jhint);
+        (*mEnv)->DeleteLocalRef(mEnv, jhint);
+    }
+}
+
 SDL_bool Android_JNI_GetAccelerometerValues(float values[3])
 {
     int i;
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index 8fe18d6..7d4ded8 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -34,6 +34,7 @@ extern "C" {
 
 /* Interface from the SDL library into the Android Java activity */
 extern void Android_JNI_SetActivityTitle(const char *title);
+extern void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint);
 extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]);
 extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect);
 extern void Android_JNI_HideTextInput(void);
diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c
index 68bc7a7..4b8ac7f 100644
--- a/src/video/android/SDL_androidwindow.c
+++ b/src/video/android/SDL_androidwindow.c
@@ -29,6 +29,7 @@
 
 #include "SDL_androidvideo.h"
 #include "SDL_androidwindow.h"
+#include "SDL_hints.h"
 
 int
 Android_CreateWindow(_THIS, SDL_Window * window)
@@ -42,6 +43,9 @@ Android_CreateWindow(_THIS, SDL_Window * window)
     Android_PauseSem = SDL_CreateSemaphore(0);
     Android_ResumeSem = SDL_CreateSemaphore(0);
 
+    /* Set orientation */
+    Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
+
     /* Adjust the window data to match the screen */
     window->x = 0;
     window->y = 0;