hardcoredaniel
2016-10-02 14:12:33 UTC
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
 ***************************************************************************
****/
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
 ***************************************************************************
****/