diff --git a/android-project/app/build.gradle b/android-project/app/build.gradle index 3fe554067..2475c1714 100644 --- a/android-project/app/build.gradle +++ b/android-project/app/build.gradle @@ -8,14 +8,14 @@ else { } android { - compileSdkVersion 16 + compileSdkVersion 19 buildToolsVersion "26.0.1" defaultConfig { if (buildAsApplication) { applicationId "org.libsdl.app" } minSdkVersion 14 - targetSdkVersion 16 + targetSdkVersion 19 versionCode 1 versionName "1.0" externalNativeBuild { @@ -65,4 +65,4 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) testCompile 'junit:junit:4.12' -} \ No newline at end of file +} diff --git a/android-project/app/jni/Application.mk b/android-project/app/jni/Application.mk index e84be0235..246136dc6 100644 --- a/android-project/app/jni/Application.mk +++ b/android-project/app/jni/Application.mk @@ -5,5 +5,5 @@ APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 -# Min SDK level +# Min runtime API level APP_PLATFORM=android-14 diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 3768310d7..750db69fa 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -213,19 +213,7 @@ public class SDLActivity extends Activity { setContentView(mLayout); - /* - * Per SDL_androidwindow.c, Android will only ever have one window, and that window - * is always flagged SDL_WINDOW_FULLSCREEN. Let's treat it as an immersive fullscreen - * window for Android UI purposes, as a result. - */ - int iFlags = - //View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | // Only available since API 19 - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_FULLSCREEN; - - getWindow().getDecorView().setSystemUiVisibility(iFlags); + setWindowStyle(false); // Get filename from "Open with" of another application Intent intent = getIntent(); @@ -408,7 +396,7 @@ public class SDLActivity extends Activity { // Messages from the SDLMain thread static final int COMMAND_CHANGE_TITLE = 1; - static final int COMMAND_UNUSED = 2; + static final int COMMAND_CHANGE_WINDOW_STYLE = 2; static final int COMMAND_TEXTEDIT_HIDE = 3; static final int COMMAND_SET_KEEP_SCREEN_ON = 5; @@ -447,6 +435,29 @@ public class SDLActivity extends Activity { Log.e(TAG, "error handling message, getContext() returned no Activity"); } break; + case COMMAND_CHANGE_WINDOW_STYLE: + if (context instanceof Activity) { + Window window = ((Activity) context).getWindow(); + if (window != null) { + if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) { + int flags = 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; + window.getDecorView().setSystemUiVisibility(flags); + window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } else { + int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + window.getDecorView().setSystemUiVisibility(flags); + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + } + } else { + Log.e(TAG, "error handling message, getContext() returned no Activity"); + } + break; case COMMAND_TEXTEDIT_HIDE: if (mTextEdit != null) { // Note: On some devices setting view to GONE creates a flicker in landscape. @@ -524,6 +535,14 @@ public class SDLActivity extends Activity { return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); } + /** + * This method is called by SDL using JNI. + */ + public static void setWindowStyle(boolean fullscreen) { + // Called from SDLMain() thread and can't directly affect the view + mSingleton.sendCommand(COMMAND_CHANGE_WINDOW_STYLE, fullscreen ? 1 : 0); + } + /** * This method is called by SDL using JNI. * This is a static method for JNI convenience, it calls a non-static method @@ -637,7 +656,7 @@ public class SDLActivity extends Activity { if (bundle == null) { return false; } - String prefix = "SDL_ENV."; + String prefix = "SDL_ENV."; final int trimLength = prefix.length(); for (String key : bundle.keySet()) { if (key.startsWith(prefix)) { diff --git a/docs/README-android.md b/docs/README-android.md index 1e9e8eff8..2d205347d 100644 --- a/docs/README-android.md +++ b/docs/README-android.md @@ -14,7 +14,7 @@ supported, but you can use the "android-project-ant" directory as a template. Requirements ================================================================================ -Android SDK (version 16 or later) +Android SDK (version 19 or later) https://developer.android.com/sdk/index.html Android NDK r10e or later diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index f09f91840..c40c6764f 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -209,6 +209,7 @@ static jclass mActivityClass; /* method signatures */ static jmethodID midGetNativeSurface; static jmethodID midSetActivityTitle; +static jmethodID midSetWindowStyle; static jmethodID midSetOrientation; static jmethodID midGetContext; static jmethodID midIsAndroidTV; @@ -302,6 +303,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c "getNativeSurface","()Landroid/view/Surface;"); midSetActivityTitle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setActivityTitle","(Ljava/lang/String;)Z"); + midSetWindowStyle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "setWindowStyle","(Z)V"); midSetOrientation = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setOrientation","(IIZLjava/lang/String;)V"); midGetContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, @@ -332,7 +335,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); if (!midGetNativeSurface || - !midSetActivityTitle || !midSetOrientation || !midGetContext || !midIsAndroidTV || !midInputGetInputDeviceIds || + !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsAndroidTV || !midInputGetInputDeviceIds || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables|| !midGetDisplayDPI) { @@ -907,6 +910,12 @@ void Android_JNI_SetActivityTitle(const char *title) (*mEnv)->DeleteLocalRef(mEnv, jtitle); } +void Android_JNI_SetWindowStyle(SDL_bool fullscreen) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetWindowStyle, fullscreen ? 1 : 0); +} + void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint) { JNIEnv *mEnv = Android_JNI_GetEnv(); diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index e26804cbc..c800dc651 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_SetWindowStyle(SDL_bool fullscreen); extern void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint); extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]); diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index c291c54a8..357f5cf17 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/src/video/android/SDL_androidvideo.c @@ -120,6 +120,7 @@ Android_CreateDevice(int devindex) device->CreateSDLWindow = Android_CreateWindow; device->SetWindowTitle = Android_SetWindowTitle; + device->SetWindowFullscreen = Android_SetWindowFullscreen; device->DestroyWindow = Android_DestroyWindow; device->GetWindowWMInfo = Android_GetWindowWMInfo; @@ -220,7 +221,7 @@ Android_SetScreenResolution(int width, int height, Uint32 format, float rate) /* Update the resolution of the desktop mode, so that the window can be properly resized. The screen resolution change can for - example happen when the Activity enters or exists immersive mode, + example happen when the Activity enters or exits immersive mode, which can happen after VideoInit(). */ device = SDL_GetVideoDevice(); @@ -234,16 +235,17 @@ Android_SetScreenResolution(int width, int height, Uint32 format, float rate) } if (Android_Window) { - SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, width, height); - /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event * will fall back to the old mode */ display = SDL_GetDisplayForWindow(Android_Window); - display->current_mode.format = format; - display->current_mode.w = width; - display->current_mode.h = height; - display->current_mode.refresh_rate = rate; + display->display_modes[0].format = format; + display->display_modes[0].w = width; + display->display_modes[0].h = height; + display->display_modes[0].refresh_rate = rate; + display->current_mode = display->display_modes[0]; + + SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, width, height); } } diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c index b38d13083..f1cbf5861 100644 --- a/src/video/android/SDL_androidwindow.c +++ b/src/video/android/SDL_androidwindow.c @@ -53,7 +53,6 @@ Android_CreateWindow(_THIS, SDL_Window * window) window->h = Android_ScreenHeight; window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */ - window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */ window->flags &= ~SDL_WINDOW_HIDDEN; window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */ window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ @@ -98,6 +97,12 @@ Android_SetWindowTitle(_THIS, SDL_Window * window) Android_JNI_SetActivityTitle(window->title); } +void +Android_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +{ + Android_JNI_SetWindowStyle(fullscreen); +} + void Android_DestroyWindow(_THIS, SDL_Window * window) { diff --git a/src/video/android/SDL_androidwindow.h b/src/video/android/SDL_androidwindow.h index 32d92e492..df99567ac 100644 --- a/src/video/android/SDL_androidwindow.h +++ b/src/video/android/SDL_androidwindow.h @@ -28,6 +28,7 @@ extern int Android_CreateWindow(_THIS, SDL_Window * window); extern void Android_SetWindowTitle(_THIS, SDL_Window * window); +extern void Android_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern void Android_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info);