Discussion:
[SDL] Improved Android patch to disable system bars
hardcoredaniel
2016-10-02 14:12:33 UTC
Permalink
Hi,

some time ago somebody posted a patch to dim the system bars on Android. I
don't remember anymore who it was, and I have lost the mail with the
original patch. I'm not sure either whether it went into bugzilla.
Nevertheless, I was using the patch successfully for a while.

Now that Android supports a "sticky immersive mode", I have improved the
patch. If the original person recognizes it, please review. Of course, any
other feedback is welcome as well.

Please ignore the additional code in SDL_hints.h

Regards,

Daniel

--- SDL_snapshot/android-project/AndroidManifest.xml    2016-10-02 09:27:
31.000000000 +0200
+++ SDL_patches/android-project/AndroidManifest.xml    2016-10-02 13:29:
01.203126644 +0200
@@ -9,12 +9,13 @@
       android:installLocation="auto">
 
     <!-- Android 2.3.3 -->
-    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="12" />
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
 
     <!-- OpenGL ES 2.0 -->
     <uses-feature android:glEsVersion="0x00020000" />
 
-    <!-- Allow writing to external storage -->
+    <!-- Allow reading & writing to external storage -->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_
STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_
STORAGE" />
 
     <!-- if you want to capture audio, uncomment this. -->

--- SDL_snapshot/android-project/src/org/libsdl/app/SDLActivity.java    2016
-10-02 09:27:31.000000000 +0200
+++ SDL_patches/android-project/src/org/libsdl/app/SDLActivity.java    2016-
10-02 14:51:36.873309659 +0200
@@ -17,6 +17,7 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsoluteLayout;
 import android.widget.RelativeLayout;
 import android.widget.Button;
 import android.widget.LinearLayout;
@@ -36,6 +37,8 @@
 public class SDLActivity extends Activity {
     private static final String TAG = "SDL";
 
+    private static final String SDL_HINT_ANDROID_HIDE_SYSTEM_BARS = "SDL_
ANDROID_HIDE_SYSTEM_BARS";
+
     // Keep track of the paused state
     public static boolean mIsPaused, mIsSurfaceReady, mHasFocus;
     public static boolean mExitCalledFromJava;
@@ -166,6 +169,13 @@
         // Set up the surface
         mSurface = new SDLSurface(getApplication());
 
+        nativeAddHintCallback(SDL_HINT_ANDROID_HIDE_SYSTEM_BARS, new
SDLHintCallback() {
+            @Override
+            public void callback(String name, String oldValue, String
newValue) {
+                updateSystemBarsStatus(newValue);
+            }
+        });
+       
         if(Build.VERSION.SDK_INT >= 12) {
             mJoystickHandler = new SDLJoystickHandler_API12();
         }
@@ -213,6 +223,8 @@
         }
 
         SDLActivity.handleResume();
+       
+        updateSystemBarsStatus(nativeGetHint(SDL_HINT_ANDROID_HIDE_SYSTEM_
BARS));
     }
 
 
@@ -325,6 +337,30 @@
         mSingleton.finish();
     }
 
+    void updateSystemBarsStatus(String value) {
+        if ("1".equals(value)) {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    // first try immersive mode (sticky immersive)
+                    if (Build.VERSION.SDK_INT >= 19) {
+                        getWindow().getDecorView().setSystemUiVisibility(
+                                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_
NAVIGATION
+                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                                | View.SYSTEM_UI_FLAG_FULLSCREEN
+                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                    } else {
+                        // if not available, use at least low profile mode
+                        if (Build.VERSION.SDK_INT >= 14) {
+                            getWindow().getDecorView().
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
+                        }
+                    }
+                }
+            });
+        }
+    }
 
     // Messages from the SDLMain thread
     static final int COMMAND_CHANGE_TITLE = 1;
@@ -437,6 +473,10 @@
                                                int is_accelerometer, int
nbuttons,
                                                int naxes, int nhats, int
nballs);
     public static native int nativeRemoveJoystick(int device_id);
+    interface SDLHintCallback {
+        void callback(String name, String oldValue, String newValue);
+    }
+    public static native void nativeAddHintCallback(String name,
SDLHintCallback callback);
     public static native String nativeGetHint(String name);
 
     /**

--- SDL_snapshot/include/SDL_hints.h    2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/include/SDL_hints.h    2016-10-02 11:38:21.092649566 +0200
@@ -689,6 +689,30 @@
 #define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"
 
 /**
+ * \brief A hint to control whether the system shall remember the preferred
fullscreen mode.
+ *
+ * This hint will work for WinRT only.
+ *
+ * The variable can be set to the following values:
+ *    "0"       - No action. System does not remember whether the app wants
to run in fullscreen.
+ *    "1"       - Remember preferred app setting (fullscreen or windowed).
+ *
+ * The default is "0".
+ *
+ */
+#define SDL_HINT_WINRT_REMEMBER_WINDOW_FULLSCREEN_PREFERENCE "SDL_WINRT_
REMEMBER_WINDOW_FULLSCREEN_PREFERENCE"
+
+/**
+ * \brief A hint to control whether an Android app shall try to dim resp.
remove the system bars.
+ *
+ * This hint, when set to 1, will try to set "low profile mode" or "sticky
immersive mode",
+ * depending on which Android API was found. If the API version is too low
for either,
+ * nothing will happen.
+ *
+ */
+#define SDL_HINT_ANDROID_HIDE_SYSTEM_BARS "SDL_ANDROID_HIDE_SYSTEM_BARS"
+
+/**
  *  \brief  An enumeration of hint priorities
  */
 typedef enum

--- SDL_snapshot/src/core/android/SDL_android.c    2016-10-02 09:27:
31.000000000 +0200
+++ SDL_patches/src/core/android/SDL_android.c    2016-10-02 11:49:
15.985195517 +0200
@@ -421,6 +421,32 @@
     return result;
 }
 
+void Android_JNI_HintCallback(void *userdata, const char *name, const char
*oldValue, const char *newValue) {
+    JNIEnv *env = Android_JNI_GetEnv();
+
+    jobject callback = (jobject)userdata;
+   jclass cls = (*env)->GetObjectClass(env, callback);
+    jmethodID method = (*env)->GetMethodID(env, cls, "callback", "(Ljava/
lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+
+    jstring javaName     = (*env)->NewStringUTF(env, name);
+    jstring javaOldValue = (*env)->NewStringUTF(env, oldValue);
+    jstring javaNewValue = (*env)->NewStringUTF(env, newValue);
+
+    (*env)->CallVoidMethod(env, callback, method, javaName, javaOldValue,
javaNewValue);
+
+    (*env)->DeleteLocalRef(env, javaName);
+    (*env)->DeleteLocalRef(env, javaOldValue);
+    (*env)->DeleteLocalRef(env, javaNewValue);
+}
+
+void Java_org_libsdl_app_SDLActivity_nativeAddHintCallback(JNIEnv* env,
jclass cls, jstring name, jobject callback) {
+    const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
+
+    SDL_AddHintCallback(utfname, Android_JNI_HintCallback, (*env)->
NewGlobalRef(env, callback));
+
+    (*env)->ReleaseStringUTFChars(env, name, utfname);   
+}
+
 /**************************************************************************
*****
              Functions called by SDL into Java
 ***************************************************************************
****/
hardcoredaniel
2016-10-04 18:56:37 UTC
Permalink
Ok, it is in now:

https://bugzilla.libsdl.org/show_bug.cgi?id=3445



---------- Původní zpráva ----------
Od: Sam Lantinga <***@libsdl.org>
Komu: SDL Development List <***@lists.libsdl.org>
Datum: 4. 10. 2016 20:35:50
Předmět: Re: [SDL] Improved Android patch to disable system bars

"


Thanks! Can you please submit it to bugzilla so it doesn't get lost?


http://bugzilla.libsdl.org(http://bugzilla.libsdl.org)




On Sun, Oct 2, 2016 at 7:12 AM, hardcoredaniel <***@seznam.cz
(mailto:***@seznam.cz)> wrote:
"
Hi,

some time ago somebody posted a patch to dim the system bars on Android. I
don't remember anymore who it was, and I have lost the mail with the
original patch. I'm not sure either whether it went into bugzilla.
Nevertheless, I was using the patch successfully for a while.

Now that Android supports a "sticky immersive mode", I have improved the
patch. If the original person recognizes it, please review. Of course, any
other feedback is welcome as well.

Please ignore the additional code in SDL_hints.h

Regards,

Daniel

--- SDL_snapshot/android-project/ AndroidManifest.xml    2016-10-02 09:27:
31.000000000 +0200
+++ SDL_patches/android-project/ AndroidManifest.xml    2016-10-02 13:29:
01.203126644 +0200
@@ -9,12 +9,13 @@
       android:installLocation="auto" >
 
     <!-- Android 2.3.3 -->
-    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="12" />
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
 
     <!-- OpenGL ES 2.0 -->
     <uses-feature android:glEsVersion=" 0x00020000" />
 
-    <!-- Allow writing to external storage -->
+    <!-- Allow reading & writing to external storage -->
+    <uses-permission android:name="android. permission.READ_EXTERNAL_
STORAGE" />
     <uses-permission android:name="android. permission.WRITE_EXTERNAL_
STORAGE" />
 
     <!-- if you want to capture audio, uncomment this. -->

--- SDL_snapshot/android-project/ src/org/libsdl/app/ SDLActivity.java   
2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/android-project/ src/org/libsdl/app/ SDLActivity.java   
2016-10-02 14:51:36.873309659 +0200
@@ -17,6 +17,7 @@
 import android.view.inputmethod. EditorInfo;
 import android.view.inputmethod. InputConnection;
 import android.view.inputmethod. InputMethodManager;
+import android.widget.AbsoluteLayout;
 import android.widget.RelativeLayout;
 import android.widget.Button;
 import android.widget.LinearLayout;
@@ -36,6 +37,8 @@
 public class SDLActivity extends Activity {
     private static final String TAG = "SDL";
 
+    private static final String SDL_HINT_ANDROID_HIDE_SYSTEM_ BARS = "SDL_
ANDROID_HIDE_SYSTEM_BARS" ;
+
     // Keep track of the paused state
     public static boolean mIsPaused, mIsSurfaceReady, mHasFocus;
     public static boolean mExitCalledFromJava;
@@ -166,6 +169,13 @@
         // Set up the surface
         mSurface = new SDLSurface(getApplication());
 
+        nativeAddHintCallback(SDL_ HINT_ANDROID_HIDE_SYSTEM_BARS, new
SDLHintCallback() {
+            @Override
+            public void callback(String name, String oldValue, String
newValue) {
+                updateSystemBarsStatus( newValue);
+            }
+        });
+       
         if(Build.VERSION.SDK_INT >= 12) {
             mJoystickHandler = new SDLJoystickHandler_API12();
         }
@@ -213,6 +223,8 @@
         }
 
         SDLActivity.handleResume();
+       
+        updateSystemBarsStatus( nativeGetHint(SDL_HINT_ ANDROID_HIDE_SYSTEM
_BARS));
     }
 
 
@@ -325,6 +337,30 @@
         mSingleton.finish();
     }
 
+    void updateSystemBarsStatus(String value) {
+        if ("1".equals(value)) {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    // first try immersive mode (sticky immersive)
+                    if (Build.VERSION.SDK_INT >= 19) {
+                        getWindow().getDecorView(). setSystemUiVisibility(
+                                View.SYSTEM_UI_FLAG_LAYOUT_ STABLE
+                                | View.SYSTEM_UI_FLAG_LAYOUT_ HIDE_
NAVIGATION
+                                | View.SYSTEM_UI_FLAG_LAYOUT_ FULLSCREEN
+                                | View.SYSTEM_UI_FLAG_HIDE_ NAVIGATION
+                                | View.SYSTEM_UI_FLAG_FULLSCREEN
+                                | View.SYSTEM_UI_FLAG_IMMERSIVE_ STICKY);
+                    } else {
+                        // if not available, use at least low profile mode
+                        if (Build.VERSION.SDK_INT >= 14) {
+                            getWindow().getDecorView().
setSystemUiVisibility(View. SYSTEM_UI_FLAG_LOW_PROFILE);
+                        }
+                    }
+                }
+            });
+        }
+    }
 
     // Messages from the SDLMain thread
     static final int COMMAND_CHANGE_TITLE = 1;
@@ -437,6 +473,10 @@
                                                 int is_accelerometer, int
nbuttons,
                                                 int naxes, int nhats, int
nballs);
     public static native int nativeRemoveJoystick(int device_id);
+    interface SDLHintCallback {
+        void callback(String name, String oldValue, String newValue);
+    }
+    public static native void nativeAddHintCallback(String name,
SDLHintCallback callback);
     public static native String nativeGetHint(String name);
 
     /**

--- SDL_snapshot/include/SDL_ hints.h    2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/include/SDL_hints. h    2016-10-02 11:38:21.092649566 +0200
@@ -689,6 +689,30 @@
 #define SDL_HINT_BMP_SAVE_LEGACY_ FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"
 
 /**
+ * \brief A hint to control whether the system shall remember the preferred
fullscreen mode.
+ *
+ * This hint will work for WinRT only.
+ *
+ * The variable can be set to the following values:
+ *    "0"       - No action. System does not remember whether the app wants
to run in fullscreen.
+ *    "1"       - Remember preferred app setting (fullscreen or windowed).
+ *
+ * The default is "0".
+ *
+ */
+#define SDL_HINT_WINRT_REMEMBER_ WINDOW_FULLSCREEN_PREFERENCE "SDL_WINRT_
REMEMBER_WINDOW_ FULLSCREEN_PREFERENCE"
+
+/**
+ * \brief A hint to control whether an Android app shall try to dim resp.
remove the system bars.
+ *
+ * This hint, when set to 1, will try to set "low profile mode" or "sticky
immersive mode",
+ * depending on which Android API was found. If the API version is too low
for either,
+ * nothing will happen.
+ *
+ */
+#define SDL_HINT_ANDROID_HIDE_SYSTEM_ BARS "SDL_ANDROID_HIDE_SYSTEM_BARS"
+
+/**
  *  \brief  An enumeration of hint priorities
  */
 typedef enum

--- SDL_snapshot/src/core/android/ SDL_android.c    2016-10-02 09:27:
31.000000000 +0200
+++ SDL_patches/src/core/android/ SDL_android.c    2016-10-02 11:49:
15.985195517 +0200
@@ -421,6 +421,32 @@
     return result;
 }
 
+void Android_JNI_HintCallback(void *userdata, const char *name, const char
*oldValue, const char *newValue) {
+    JNIEnv *env = Android_JNI_GetEnv();
+
+    jobject callback = (jobject)userdata;
+   jclass cls = (*env)->GetObjectClass(env, callback);
+    jmethodID method = (*env)->GetMethodID(env, cls, "callback", "(Ljava/
lang/String;Ljava/ lang/String;Ljava/lang/String; )V");
+
+    jstring javaName     = (*env)->NewStringUTF(env, name);
+    jstring javaOldValue = (*env)->NewStringUTF(env, oldValue);
+    jstring javaNewValue = (*env)->NewStringUTF(env, newValue);
+
+    (*env)->CallVoidMethod(env, callback, method, javaName, javaOldValue,
javaNewValue);
+
+    (*env)->DeleteLocalRef(env, javaName);
+    (*env)->DeleteLocalRef(env, javaOldValue);
+    (*env)->DeleteLocalRef(env, javaNewValue);
+}
+
+void Java_org_libsdl_app_ SDLActivity_ nativeAddHintCallback(JNIEnv* env,
jclass cls, jstring name, jobject callback) {
+    const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
+
+    SDL_AddHintCallback(utfname, Android_JNI_HintCallback, (*env)->
NewGlobalRef(env, callback));
+
+    (*env)->ReleaseStringUTFChars( env, name, utfname);   
+}
+
 /**************************** ****************************** **************
*******
              Functions called by SDL into Java
 ***************************** ****************************** **************
******/



______________________________ _________________
SDL mailing list
***@lists.libsdl.org(mailto:***@lists.libsdl.org)
http://lists.libsdl.org/ listinfo.cgi/sdl-libsdl.org
(http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org)

"

Loading...