Merge pull request #27010 from BastiaanOlij/restructure_android_glue

Restructuring android glue code to make it easier to extend
This commit is contained in:
Rémi Verschelde 2019-04-06 00:09:16 +02:00 committed by GitHub
commit a9a4936518
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 691 additions and 374 deletions

View file

@ -16,8 +16,10 @@ android_files = [
'dir_access_jandroid.cpp', 'dir_access_jandroid.cpp',
'thread_jandroid.cpp', 'thread_jandroid.cpp',
'audio_driver_jandroid.cpp', 'audio_driver_jandroid.cpp',
'java_glue.cpp', 'java_godot_lib_jni.cpp',
'java_class_wrapper.cpp', 'java_class_wrapper.cpp',
'java_godot_wrapper.cpp',
'java_godot_io_wrapper.cpp',
# 'power_android.cpp' # 'power_android.cpp'
] ]

View file

@ -33,7 +33,7 @@
#include "servers/audio_server.h" #include "servers/audio_server.h"
#include "java_glue.h" #include "java_godot_lib_jni.h"
class AudioDriverAndroid : public AudioDriver { class AudioDriverAndroid : public AudioDriver {

View file

@ -32,7 +32,7 @@
#define DIR_ACCESS_JANDROID_H #define DIR_ACCESS_JANDROID_H
#include "core/os/dir_access.h" #include "core/os/dir_access.h"
#include "java_glue.h" #include "java_godot_lib_jni.h"
#include <stdio.h> #include <stdio.h>
class DirAccessJAndroid : public DirAccess { class DirAccessJAndroid : public DirAccess {

View file

@ -32,7 +32,7 @@
#define FILE_ACCESS_JANDROID_H #define FILE_ACCESS_JANDROID_H
#include "core/os/file_access.h" #include "core/os/file_access.h"
#include "java_glue.h" #include "java_godot_lib_jni.h"
class FileAccessJAndroid : public FileAccess { class FileAccessJAndroid : public FileAccess {
static jobject io; static jobject io;

View file

@ -606,6 +606,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
for (int i = 0; i < singleton_count; i++) { for (int i = 0; i < singleton_count; i++) {
singletons[i].onMainDestroy(); singletons[i].onMainDestroy();
} }
GodotLib.ondestroy(this);
super.onDestroy(); super.onDestroy();
} }

View file

@ -46,6 +46,7 @@ public class GodotLib {
*/ */
public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion); public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
public static native void ondestroy(Godot p_instance);
public static native void setup(String[] p_cmdline); public static native void setup(String[] p_cmdline);
public static native void resize(int width, int height); public static native void resize(int width, int height);
public static native void newcontext(boolean p_32_bits); public static native void newcontext(boolean p_32_bits);

View file

@ -0,0 +1,207 @@
/*************************************************************************/
/* java_godot_io_wrapper.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "java_godot_io_wrapper.h"
#include "core/error_list.h"
// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
// For GodotIO we call all access methods from our thread and we thus get a valid JNIEnv
// from ThreadAndroid.
GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance) {
godot_io_instance = p_env->NewGlobalRef(p_godot_io_instance);
if (godot_io_instance) {
cls = p_env->GetObjectClass(godot_io_instance);
if (cls) {
cls = (jclass)p_env->NewGlobalRef(cls);
} else {
// this is a pretty serious fail.. bail... pointers will stay 0
return;
}
_open_URI = p_env->GetMethodID(cls, "openURI", "(Ljava/lang/String;)I");
_get_data_dir = p_env->GetMethodID(cls, "getDataDir", "()Ljava/lang/String;");
_get_locale = p_env->GetMethodID(cls, "getLocale", "()Ljava/lang/String;");
_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
_get_unique_ID = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;)V");
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;");
_play_video = p_env->GetMethodID(cls, "playVideo", "(Ljava/lang/String;)V");
_is_video_playing = p_env->GetMethodID(cls, "isVideoPlaying", "()Z");
_pause_video = p_env->GetMethodID(cls, "pauseVideo", "()V");
_stop_video = p_env->GetMethodID(cls, "stopVideo", "()V");
}
}
GodotIOJavaWrapper::~GodotIOJavaWrapper() {
// nothing to do here for now
}
jobject GodotIOJavaWrapper::get_instance() {
return godot_io_instance;
}
Error GodotIOJavaWrapper::open_uri(const String &p_uri) {
if (_open_URI) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_uri.utf8().get_data());
return env->CallIntMethod(godot_io_instance, _open_URI, jStr) ? ERR_CANT_OPEN : OK;
} else {
return ERR_UNAVAILABLE;
}
}
String GodotIOJavaWrapper::get_user_data_dir() {
if (_get_data_dir) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_data_dir);
return jstring_to_string(s, env);
} else {
return String();
}
}
String GodotIOJavaWrapper::get_locale() {
if (_get_locale) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_locale);
return jstring_to_string(s, env);
} else {
return String();
}
}
String GodotIOJavaWrapper::get_model() {
if (_get_model) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_model);
return jstring_to_string(s, env);
} else {
return String();
}
}
int GodotIOJavaWrapper::get_screen_dpi() {
if (_get_screen_DPI) {
JNIEnv *env = ThreadAndroid::get_env();
return env->CallIntMethod(godot_io_instance, _get_screen_DPI);
} else {
return 160;
}
}
String GodotIOJavaWrapper::get_unique_id() {
if (_get_unique_ID) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_unique_ID);
return jstring_to_string(s, env);
} else {
return String();
}
}
bool GodotIOJavaWrapper::has_vk() {
return (_show_keyboard != 0) && (_hide_keyboard != 0);
}
void GodotIOJavaWrapper::show_vk(const String &p_existing) {
if (_show_keyboard) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr);
}
}
void GodotIOJavaWrapper::hide_vk() {
if (_hide_keyboard) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io_instance, _hide_keyboard);
}
}
void GodotIOJavaWrapper::set_screen_orientation(int p_orient) {
if (_set_screen_orientation) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io_instance, _set_screen_orientation, p_orient);
}
}
String GodotIOJavaWrapper::get_system_dir(int p_dir) {
if (_get_system_dir) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
return jstring_to_string(s, env);
} else {
return String(".");
}
}
void GodotIOJavaWrapper::play_video(const String &p_path) {
// Why is this not here?!?!
}
bool GodotIOJavaWrapper::is_video_playing() {
if (_is_video_playing) {
JNIEnv *env = ThreadAndroid::get_env();
return env->CallBooleanMethod(godot_io_instance, _is_video_playing);
} else {
return false;
}
}
void GodotIOJavaWrapper::pause_video() {
if (_pause_video) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io_instance, _pause_video);
}
}
void GodotIOJavaWrapper::stop_video() {
if (_stop_video) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io_instance, _stop_video);
}
}
// volatile because it can be changed from non-main thread and we need to
// ensure the change is immediately visible to other threads.
static volatile int virtual_keyboard_height;
int GodotIOJavaWrapper::get_vk_height() {
return virtual_keyboard_height;
}
void GodotIOJavaWrapper::set_vk_height(int p_height) {
virtual_keyboard_height = p_height;
}

View file

@ -0,0 +1,88 @@
/*************************************************************************/
/* java_godot_io_wrapper.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
// note, swapped java and godot around in the file name so all the java
// wrappers are together
#ifndef JAVA_GODOT_IO_WRAPPER_H
#define JAVA_GODOT_IO_WRAPPER_H
#include <android/log.h>
#include <jni.h>
#include "string_android.h"
// Class that makes functions in java/src/org/godotengine/godot/GodotIO.java callable from C++
class GodotIOJavaWrapper {
private:
jobject godot_io_instance;
jclass cls;
jmethodID _open_URI = 0;
jmethodID _get_data_dir = 0;
jmethodID _get_locale = 0;
jmethodID _get_model = 0;
jmethodID _get_screen_DPI = 0;
jmethodID _get_unique_ID = 0;
jmethodID _show_keyboard = 0;
jmethodID _hide_keyboard = 0;
jmethodID _set_screen_orientation = 0;
jmethodID _get_system_dir = 0;
jmethodID _play_video = 0;
jmethodID _is_video_playing = 0;
jmethodID _pause_video = 0;
jmethodID _stop_video = 0;
public:
GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance);
~GodotIOJavaWrapper();
jobject get_instance();
Error open_uri(const String &p_uri);
String get_user_data_dir();
String get_locale();
String get_model();
int get_screen_dpi();
String get_unique_id();
bool has_vk();
void show_vk(const String &p_existing);
void hide_vk();
int get_vk_height();
void set_vk_height(int p_height);
void set_screen_orientation(int p_orient);
String get_system_dir(int p_dir);
void play_video(const String &p_path);
bool is_video_playing();
void pause_video();
void stop_video();
};
#endif /* !JAVA_GODOT_IO_WRAPPER_H */

View file

@ -1,5 +1,5 @@
/*************************************************************************/ /*************************************************************************/
/* java_glue.cpp */ /* java_godot_lib_jni.cpp */
/*************************************************************************/ /*************************************************************************/
/* This file is part of: */ /* This file is part of: */
/* GODOT ENGINE */ /* GODOT ENGINE */
@ -28,7 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "java_glue.h" #include "java_godot_lib_jni.h"
#include "java_godot_io_wrapper.h"
#include "java_godot_wrapper.h"
#include "android/asset_manager_jni.h" #include "android/asset_manager_jni.h"
#include "audio_driver_jandroid.h" #include "audio_driver_jandroid.h"
#include "core/engine.h" #include "core/engine.h"
@ -47,6 +50,8 @@
static JavaClassWrapper *java_class_wrapper = NULL; static JavaClassWrapper *java_class_wrapper = NULL;
static OS_Android *os_android = NULL; static OS_Android *os_android = NULL;
static GodotJavaWrapper *godot_java = NULL;
static GodotIOJavaWrapper *godot_io_java = NULL;
struct jvalret { struct jvalret {
@ -588,181 +593,23 @@ TST tst;
static bool initialized = false; static bool initialized = false;
static int step = 0; static int step = 0;
static Size2 new_size; static Size2 new_size;
static Vector3 accelerometer; static Vector3 accelerometer;
static Vector3 gravity; static Vector3 gravity;
static Vector3 magnetometer; static Vector3 magnetometer;
static Vector3 gyroscope; static Vector3 gyroscope;
static HashMap<String, JNISingleton *> jni_singletons; static HashMap<String, JNISingleton *> jni_singletons;
static jobject godot_io;
typedef void (*GFXInitFunc)(void *ud, bool gl2);
static jmethodID _on_video_init = 0;
static jmethodID _restart = 0;
static jobject _godot_instance;
static jmethodID _openURI = 0;
static jmethodID _getDataDir = 0;
static jmethodID _getLocale = 0;
static jmethodID _getClipboard = 0;
static jmethodID _setClipboard = 0;
static jmethodID _getModel = 0;
static jmethodID _getScreenDPI = 0;
static jmethodID _showKeyboard = 0;
static jmethodID _hideKeyboard = 0;
static jmethodID _setScreenOrientation = 0;
static jmethodID _getUniqueID = 0;
static jmethodID _getSystemDir = 0;
static jmethodID _getGLESVersionCode = 0;
static jmethodID _playVideo = 0;
static jmethodID _isVideoPlaying = 0;
static jmethodID _pauseVideo = 0;
static jmethodID _stopVideo = 0;
static jmethodID _setKeepScreenOn = 0;
static jmethodID _alertDialog = 0;
static jmethodID _requestPermission = 0;
static void _gfx_init_func(void *ud, bool gl2) {
}
static int _open_uri(const String &p_uri) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_uri.utf8().get_data());
return env->CallIntMethod(godot_io, _openURI, jStr);
}
static String _get_user_data_dir() {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io, _getDataDir);
return jstring_to_string(s, env);
}
static String _get_locale() {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io, _getLocale);
return jstring_to_string(s, env);
}
static String _get_clipboard() {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(_godot_instance, _getClipboard);
return jstring_to_string(s, env);
}
static void _set_clipboard(const String &p_text) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_text.utf8().get_data());
env->CallVoidMethod(_godot_instance, _setClipboard, jStr);
}
static String _get_model() {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io, _getModel);
return jstring_to_string(s, env);
}
static int _get_screen_dpi() {
JNIEnv *env = ThreadAndroid::get_env();
return env->CallIntMethod(godot_io, _getScreenDPI);
}
static String _get_unique_id() {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io, _getUniqueID);
return jstring_to_string(s, env);
}
static void _show_vk(const String &p_existing) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
env->CallVoidMethod(godot_io, _showKeyboard, jStr);
}
static void _set_screen_orient(int p_orient) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io, _setScreenOrientation, p_orient);
}
static String _get_system_dir(int p_dir) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io, _getSystemDir, p_dir);
return jstring_to_string(s, env);
}
static int _get_gles_version_code() {
JNIEnv *env = ThreadAndroid::get_env();
return env->CallIntMethod(_godot_instance, _getGLESVersionCode);
}
static void _hide_vk() {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io, _hideKeyboard);
}
// virtual Error native_video_play(String p_path); // virtual Error native_video_play(String p_path);
// virtual bool native_video_is_playing(); // virtual bool native_video_is_playing();
// virtual void native_video_pause(); // virtual void native_video_pause();
// virtual void native_video_stop(); // virtual void native_video_stop();
static void _play_video(const String &p_path) {
}
static bool _is_video_playing() {
JNIEnv *env = ThreadAndroid::get_env();
return env->CallBooleanMethod(godot_io, _isVideoPlaying);
//return false;
}
static void _pause_video() {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io, _pauseVideo);
}
static void _stop_video() {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_io, _stopVideo);
}
static void _set_keep_screen_on(bool p_enabled) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(_godot_instance, _setKeepScreenOn, p_enabled);
}
static void _alert(const String &p_message, const String &p_title) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data());
jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data());
env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle);
}
static bool _request_permission(const String &p_name) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStrName = env->NewStringUTF(p_name.utf8().get_data());
return env->CallBooleanMethod(_godot_instance, _requestPermission, jStrName);
}
// volatile because it can be changed from non-main thread and we need to
// ensure the change is immediately visible to other threads.
static volatile int virtual_keyboard_height;
static int _get_vk_height() {
return virtual_keyboard_height;
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height) { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height) {
virtual_keyboard_height = p_height; if (godot_io_java) {
godot_io_java->set_vk_height(p_height);
}
} }
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion) { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion) {
@ -772,70 +619,42 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
JavaVM *jvm; JavaVM *jvm;
env->GetJavaVM(&jvm); env->GetJavaVM(&jvm);
_godot_instance = env->NewGlobalRef(activity); // create our wrapper classes
//_godot_instance=activity; godot_java = new GodotJavaWrapper(env, activity); // our activity is our godot instance is our activity..
godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
{
//setup IO Object
jclass cls = env->FindClass("org/godotengine/godot/Godot");
if (cls) {
cls = (jclass)env->NewGlobalRef(cls);
}
jfieldID fid = env->GetStaticFieldID(cls, "io", "Lorg/godotengine/godot/GodotIO;");
jobject ob = env->GetStaticObjectField(cls, fid);
jobject gob = env->NewGlobalRef(ob);
godot_io = gob;
_on_video_init = env->GetMethodID(cls, "onVideoInit", "()V");
_restart = env->GetMethodID(cls, "restart", "()V");
_setKeepScreenOn = env->GetMethodID(cls, "setKeepScreenOn", "(Z)V");
_alertDialog = env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
_getGLESVersionCode = env->GetMethodID(cls, "getGLESVersionCode", "()I");
_getClipboard = env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
_setClipboard = env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
_requestPermission = env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
if (cls) {
jclass c = env->GetObjectClass(gob);
_openURI = env->GetMethodID(c, "openURI", "(Ljava/lang/String;)I");
_getDataDir = env->GetMethodID(c, "getDataDir", "()Ljava/lang/String;");
_getLocale = env->GetMethodID(c, "getLocale", "()Ljava/lang/String;");
_getModel = env->GetMethodID(c, "getModel", "()Ljava/lang/String;");
_getScreenDPI = env->GetMethodID(c, "getScreenDPI", "()I");
_getUniqueID = env->GetMethodID(c, "getUniqueID", "()Ljava/lang/String;");
_showKeyboard = env->GetMethodID(c, "showKeyboard", "(Ljava/lang/String;)V");
_hideKeyboard = env->GetMethodID(c, "hideKeyboard", "()V");
_setScreenOrientation = env->GetMethodID(c, "setScreenOrientation", "(I)V");
_getSystemDir = env->GetMethodID(c, "getSystemDir", "(I)Ljava/lang/String;");
_playVideo = env->GetMethodID(c, "playVideo", "(Ljava/lang/String;)V");
_isVideoPlaying = env->GetMethodID(c, "isVideoPlaying", "()Z");
_pauseVideo = env->GetMethodID(c, "pauseVideo", "()V");
_stopVideo = env->GetMethodID(c, "stopVideo", "()V");
}
ThreadAndroid::make_default(jvm); ThreadAndroid::make_default(jvm);
#ifdef USE_JAVA_FILE_ACCESS #ifdef USE_JAVA_FILE_ACCESS
FileAccessJAndroid::setup(gob); FileAccessJAndroid::setup(godot_io_java->get_instance());
#else #else
jobject amgr = env->NewGlobalRef(p_asset_manager); jobject amgr = env->NewGlobalRef(p_asset_manager);
FileAccessAndroid::asset_manager = AAssetManager_fromJava(env, amgr); FileAccessAndroid::asset_manager = AAssetManager_fromJava(env, amgr);
#endif #endif
DirAccessJAndroid::setup(gob);
AudioDriverAndroid::setup(gob);
}
os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _get_gles_version_code, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, _set_clipboard, _get_clipboard, _request_permission, p_use_apk_expansion); DirAccessJAndroid::setup(godot_io_java->get_instance());
AudioDriverAndroid::setup(godot_io_java->get_instance());
os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion);
char wd[500]; char wd[500];
getcwd(wd, 500); getcwd(wd, 500);
env->CallVoidMethod(_godot_instance, _on_video_init); godot_java->on_video_init(env);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env) {
// lets cleanup
if (godot_io_java) {
delete godot_io_java;
}
if (godot_java) {
delete godot_java;
}
if (os_android) {
delete os_android;
}
} }
static void _initialize_java_modules() { static void _initialize_java_modules() {
@ -852,17 +671,12 @@ static void _initialize_java_modules() {
Vector<String> mods = modules.split(",", false); Vector<String> mods = modules.split(",", false);
if (mods.size()) { if (mods.size()) {
jobject cls = godot_java->get_class_loader();
// TODO create wrapper for class loader
JNIEnv *env = ThreadAndroid::get_env(); JNIEnv *env = ThreadAndroid::get_env();
jclass activityClass = env->FindClass("org/godotengine/godot/Godot");
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject cls = env->CallObjectMethod(_godot_instance, getClassLoader);
jclass classLoader = env->FindClass("java/lang/ClassLoader"); jclass classLoader = env->FindClass("java/lang/ClassLoader");
jmethodID findClass = env->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); jmethodID findClass = env->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
for (int i = 0; i < mods.size(); i++) { for (int i = 0; i < mods.size(); i++) {
@ -886,7 +700,7 @@ static void _initialize_java_modules() {
ERR_EXPLAIN("Couldn't find proper initialize function 'public static Godot.SingletonBase Class::initialize(Activity p_activity)' initializer for singleton class: " + m); ERR_EXPLAIN("Couldn't find proper initialize function 'public static Godot.SingletonBase Class::initialize(Activity p_activity)' initializer for singleton class: " + m);
ERR_CONTINUE(!initialize); ERR_CONTINUE(!initialize);
} }
jobject obj = env->CallStaticObjectMethod(singletonClass, initialize, _godot_instance); jobject obj = env->CallStaticObjectMethod(singletonClass, initialize, godot_java->get_activity());
env->NewGlobalRef(obj); env->NewGlobalRef(obj);
} }
} }
@ -931,7 +745,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo
return; //should exit instead and print the error return; //should exit instead and print the error
} }
java_class_wrapper = memnew(JavaClassWrapper(_godot_instance)); java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity()));
Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", java_class_wrapper)); Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", java_class_wrapper));
_initialize_java_modules(); _initialize_java_modules();
} }
@ -951,7 +765,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en
} else { } else {
// GL context recreated because it was lost; restart app to let it reload everything // GL context recreated because it was lost; restart app to let it reload everything
os_android->main_loop_end(); os_android->main_loop_end();
env->CallVoidMethod(_godot_instance, _restart); godot_java->restart(env);
step = -1; // Ensure no further steps are attempted step = -1; // Ensure no further steps are attempted
} }
} }
@ -987,18 +801,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
} }
os_android->process_accelerometer(accelerometer); os_android->process_accelerometer(accelerometer);
os_android->process_gravity(gravity); os_android->process_gravity(gravity);
os_android->process_magnetometer(magnetometer); os_android->process_magnetometer(magnetometer);
os_android->process_gyroscope(gyroscope); os_android->process_gyroscope(gyroscope);
if (os_android->main_loop_iterate()) { if (os_android->main_loop_iterate()) {
jclass cls = env->FindClass("org/godotengine/godot/Godot"); godot_java->force_quit(env);
jmethodID _finish = env->GetMethodID(cls, "forceQuit", "()V");
env->CallVoidMethod(_godot_instance, _finish);
} }
} }

View file

@ -1,5 +1,5 @@
/*************************************************************************/ /*************************************************************************/
/* java_glue.h */ /* java_godot_lib_jni.h */
/*************************************************************************/ /*************************************************************************/
/* This file is part of: */ /* This file is part of: */
/* GODOT ENGINE */ /* GODOT ENGINE */
@ -28,14 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#ifndef JAVA_GLUE_H #ifndef JAVA_GODOT_LIB_JNI_H
#define JAVA_GLUE_H #define JAVA_GODOT_LIB_JNI_H
#include <android/log.h> #include <android/log.h>
#include <jni.h> #include <jni.h>
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes thats why we have the long names)
extern "C" { extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits);
@ -63,4 +66,4 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jobject p_obj, jstring p_permission, jboolean p_result); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jobject p_obj, jstring p_permission, jboolean p_result);
} }
#endif // JAVA_GLUE_H #endif /* !JAVA_GODOT_LIB_JNI_H */

View file

@ -0,0 +1,185 @@
/*************************************************************************/
/* java_godot_wrapper.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "java_godot_wrapper.h"
// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
// For Godot we call most access methods from our thread and we thus get a valid JNIEnv
// from ThreadAndroid. For one or two we expect to pass the environment
// TODO we could probably create a base class for this...
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
godot_instance = p_env->NewGlobalRef(p_godot_instance);
// get info about our Godot class so we can get pointers and stuff...
cls = p_env->FindClass("org/godotengine/godot/Godot");
if (cls) {
cls = (jclass)p_env->NewGlobalRef(cls);
} else {
// this is a pretty serious fail.. bail... pointers will stay 0
return;
}
// get some method pointers...
_on_video_init = p_env->GetMethodID(cls, "onVideoInit", "()V");
_restart = p_env->GetMethodID(cls, "restart", "()V");
_finish = p_env->GetMethodID(cls, "forceQuit", "()V");
_set_keep_screen_on = p_env->GetMethodID(cls, "setKeepScreenOn", "(Z)V");
_alert = p_env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
_get_GLES_version_code = p_env->GetMethodID(cls, "getGLESVersionCode", "()I");
_get_clipboard = p_env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
_set_clipboard = p_env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
_request_permission = p_env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
}
GodotJavaWrapper::~GodotJavaWrapper() {
// nothing to do here for now
}
jobject GodotJavaWrapper::get_activity() {
// our godot instance is our activity
return godot_instance;
}
jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) {
if (cls) {
if (p_env == NULL)
p_env = ThreadAndroid::get_env();
jfieldID fid = p_env->GetStaticFieldID(cls, p_name, p_class);
return p_env->GetStaticObjectField(cls, fid);
} else {
return NULL;
}
}
jobject GodotJavaWrapper::get_class_loader() {
if (cls) {
JNIEnv *env = ThreadAndroid::get_env();
jmethodID getClassLoader = env->GetMethodID(cls, "getClassLoader", "()Ljava/lang/ClassLoader;");
return env->CallObjectMethod(godot_instance, getClassLoader);
} else {
return NULL;
}
}
void GodotJavaWrapper::gfx_init(bool gl2) {
// beats me what this once did, there was no code,
// but we're getting false if our GLES3 driver is initialised
// and true for our GLES2 driver
// Maybe we're supposed to communicate this back or store it?
}
void GodotJavaWrapper::on_video_init(JNIEnv *p_env) {
if (_on_video_init)
if (p_env == NULL)
p_env = ThreadAndroid::get_env();
p_env->CallVoidMethod(godot_instance, _on_video_init);
}
void GodotJavaWrapper::restart(JNIEnv *p_env) {
if (_restart)
if (p_env == NULL)
p_env = ThreadAndroid::get_env();
p_env->CallVoidMethod(godot_instance, _restart);
}
void GodotJavaWrapper::force_quit(JNIEnv *p_env) {
if (_finish)
if (p_env == NULL)
p_env = ThreadAndroid::get_env();
p_env->CallVoidMethod(godot_instance, _finish);
}
void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) {
if (_set_keep_screen_on) {
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(godot_instance, _set_keep_screen_on, p_enabled);
}
}
void GodotJavaWrapper::alert(const String &p_message, const String &p_title) {
if (_alert) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data());
jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data());
env->CallVoidMethod(godot_instance, _alert, jStrMessage, jStrTitle);
}
}
int GodotJavaWrapper::get_gles_version_code() {
JNIEnv *env = ThreadAndroid::get_env();
if (_get_GLES_version_code) {
return env->CallIntMethod(godot_instance, _get_GLES_version_code);
}
return 0;
}
bool GodotJavaWrapper::has_get_clipboard() {
return _get_clipboard != 0;
}
String GodotJavaWrapper::get_clipboard() {
if (_get_clipboard) {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_clipboard);
return jstring_to_string(s, env);
} else {
return String();
}
}
bool GodotJavaWrapper::has_set_clipboard() {
return _set_clipboard != 0;
}
void GodotJavaWrapper::set_clipboard(const String &p_text) {
if (_set_clipboard) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_text.utf8().get_data());
env->CallVoidMethod(godot_instance, _set_clipboard, jStr);
}
}
bool GodotJavaWrapper::request_permission(const String &p_name) {
if (_request_permission) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStrName = env->NewStringUTF(p_name.utf8().get_data());
return env->CallBooleanMethod(godot_instance, _request_permission, jStrName);
} else {
return false;
}
}

View file

@ -0,0 +1,81 @@
/*************************************************************************/
/* java_godot_wrapper.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
// note, swapped java and godot around in the file name so all the java
// wrappers are together
#ifndef JAVA_GODOT_WRAPPER_H
#define JAVA_GODOT_WRAPPER_H
#include <android/log.h>
#include <jni.h>
#include "string_android.h"
// Class that makes functions in java/src/org/godotengine/godot/Godot.java callable from C++
class GodotJavaWrapper {
private:
jobject godot_instance;
jclass cls;
jmethodID _on_video_init = 0;
jmethodID _restart = 0;
jmethodID _finish = 0;
jmethodID _set_keep_screen_on = 0;
jmethodID _alert = 0;
jmethodID _get_GLES_version_code = 0;
jmethodID _get_clipboard = 0;
jmethodID _set_clipboard = 0;
jmethodID _request_permission = 0;
public:
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
~GodotJavaWrapper();
jobject get_activity();
jobject get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env = NULL);
jobject get_class_loader();
void gfx_init(bool gl2);
void on_video_init(JNIEnv *p_env = NULL);
void restart(JNIEnv *p_env = NULL);
void force_quit(JNIEnv *p_env = NULL);
void set_keep_screen_on(bool p_enabled);
void alert(const String &p_message, const String &p_title);
int get_gles_version_code();
bool has_get_clipboard();
String get_clipboard();
bool has_set_clipboard();
void set_clipboard(const String &p_text);
bool request_permission(const String &p_name);
};
#endif /* !JAVA_GODOT_WRAPPER_H */

View file

@ -46,6 +46,9 @@
#include <dlfcn.h> #include <dlfcn.h>
#include "java_godot_io_wrapper.h"
#include "java_godot_wrapper.h"
class AndroidLogger : public Logger { class AndroidLogger : public Logger {
public: public:
virtual void logv(const char *p_format, va_list p_list, bool p_err) { virtual void logv(const char *p_format, va_list p_list, bool p_err) {
@ -118,15 +121,14 @@ int OS_Android::get_current_video_driver() const {
Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
bool use_gl3 = get_gl_version_code_func() >= 0x00030000; bool use_gl3 = godot_java->get_gles_version_code() >= 0x00030000;
use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3"); use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3");
bool gl_initialization_error = false; bool gl_initialization_error = false;
while (true) { while (true) {
if (use_gl3) { if (use_gl3) {
if (RasterizerGLES3::is_viable() == OK) { if (RasterizerGLES3::is_viable() == OK) {
if (gfx_init_func) godot_java->gfx_init(false);
gfx_init_func(gfx_init_ud, false);
RasterizerGLES3::register_config(); RasterizerGLES3::register_config();
RasterizerGLES3::make_current(); RasterizerGLES3::make_current();
break; break;
@ -142,8 +144,7 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
} }
} else { } else {
if (RasterizerGLES2::is_viable() == OK) { if (RasterizerGLES2::is_viable() == OK) {
if (gfx_init_func) godot_java->gfx_init(true);
gfx_init_func(gfx_init_ud, true);
RasterizerGLES2::register_config(); RasterizerGLES2::register_config();
RasterizerGLES2::make_current(); RasterizerGLES2::make_current();
break; break;
@ -195,17 +196,23 @@ void OS_Android::finalize() {
memdelete(input); memdelete(input);
} }
GodotJavaWrapper *OS_Android::get_godot_java() {
return godot_java;
}
GodotIOJavaWrapper *OS_Android::get_godot_io_java() {
return godot_io_java;
}
void OS_Android::alert(const String &p_alert, const String &p_title) { void OS_Android::alert(const String &p_alert, const String &p_title) {
//print("ALERT: %s\n", p_alert.utf8().get_data()); //print("ALERT: %s\n", p_alert.utf8().get_data());
if (alert_func) godot_java->alert(p_alert, p_title);
alert_func(p_alert, p_title);
} }
bool OS_Android::request_permission(const String &p_name) { bool OS_Android::request_permission(const String &p_name) {
if (request_permission_func)
return request_permission_func(p_name); return godot_java->request_permission(p_name);
return false;
} }
Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
@ -262,9 +269,7 @@ void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen)
void OS_Android::set_keep_screen_on(bool p_enabled) { void OS_Android::set_keep_screen_on(bool p_enabled) {
OS::set_keep_screen_on(p_enabled); OS::set_keep_screen_on(p_enabled);
if (set_keep_screen_on_func) { godot_java->set_keep_screen_on(p_enabled);
set_keep_screen_on_func(p_enabled);
}
} }
Size2 OS_Android::get_window_size() const { Size2 OS_Android::get_window_size() const {
@ -505,18 +510,16 @@ bool OS_Android::has_virtual_keyboard() const {
} }
int OS_Android::get_virtual_keyboard_height() const { int OS_Android::get_virtual_keyboard_height() const {
if (get_virtual_keyboard_height_func) { return godot_io_java->get_vk_height();
return get_virtual_keyboard_height_func();
}
ERR_PRINT("Cannot obtain virtual keyboard height."); // ERR_PRINT("Cannot obtain virtual keyboard height.");
return 0; // return 0;
} }
void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) { void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) {
if (show_virtual_keyboard_func) { if (godot_io_java->has_vk()) {
show_virtual_keyboard_func(p_existing_text); godot_io_java->show_vk(p_existing_text);
} else { } else {
ERR_PRINT("Virtual keyboard not available"); ERR_PRINT("Virtual keyboard not available");
@ -525,9 +528,9 @@ void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect
void OS_Android::hide_virtual_keyboard() { void OS_Android::hide_virtual_keyboard() {
if (hide_virtual_keyboard_func) { if (godot_io_java->has_vk()) {
hide_virtual_keyboard_func(); godot_io_java->hide_vk();
} else { } else {
ERR_PRINT("Virtual keyboard not available"); ERR_PRINT("Virtual keyboard not available");
@ -556,9 +559,7 @@ void OS_Android::set_display_size(Size2 p_size) {
Error OS_Android::shell_open(String p_uri) { Error OS_Android::shell_open(String p_uri) {
if (open_uri_func) return godot_io_java->open_uri(p_uri);
return open_uri_func(p_uri) ? ERR_CANT_OPEN : OK;
return ERR_UNAVAILABLE;
} }
String OS_Android::get_resource_dir() const { String OS_Android::get_resource_dir() const {
@ -568,23 +569,29 @@ String OS_Android::get_resource_dir() const {
String OS_Android::get_locale() const { String OS_Android::get_locale() const {
if (get_locale_func) String locale = godot_io_java->get_locale();
return get_locale_func(); if (locale != "") {
return locale;
}
return OS_Unix::get_locale(); return OS_Unix::get_locale();
} }
void OS_Android::set_clipboard(const String &p_text) { void OS_Android::set_clipboard(const String &p_text) {
if (set_clipboard_func) { // DO we really need the fallback to OS_Unix here?!
set_clipboard_func(p_text); if (godot_java->has_set_clipboard()) {
godot_java->set_clipboard(p_text);
} else { } else {
OS_Unix::set_clipboard(p_text); OS_Unix::set_clipboard(p_text);
} }
} }
String OS_Android::get_clipboard() const { String OS_Android::get_clipboard() const {
if (get_clipboard_func) {
return get_clipboard_func(); // DO we really need the fallback to OS_Unix here?!
if (godot_java->has_get_clipboard()) {
return godot_java->get_clipboard();
} }
return OS_Unix::get_clipboard(); return OS_Unix::get_clipboard();
@ -592,17 +599,16 @@ String OS_Android::get_clipboard() const {
String OS_Android::get_model_name() const { String OS_Android::get_model_name() const {
if (get_model_func) String model = godot_io_java->get_model();
return get_model_func(); if (model != "")
return model;
return OS_Unix::get_model_name(); return OS_Unix::get_model_name();
} }
int OS_Android::get_screen_dpi(int p_screen) const { int OS_Android::get_screen_dpi(int p_screen) const {
if (get_screen_dpi_func) { return godot_io_java->get_screen_dpi();
return get_screen_dpi_func();
}
return 160;
} }
String OS_Android::get_user_data_dir() const { String OS_Android::get_user_data_dir() const {
@ -610,8 +616,8 @@ String OS_Android::get_user_data_dir() const {
if (data_dir_cache != String()) if (data_dir_cache != String())
return data_dir_cache; return data_dir_cache;
if (get_user_data_dir_func) { String data_dir = godot_io_java->get_user_data_dir();
String data_dir = get_user_data_dir_func(); if (data_dir != "") {
//store current dir //store current dir
char real_current_dir_name[2048]; char real_current_dir_name[2048];
@ -638,45 +644,43 @@ String OS_Android::get_user_data_dir() const {
void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) { void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) {
if (set_screen_orientation_func) godot_io_java->set_screen_orientation(p_orientation);
set_screen_orientation_func(p_orientation);
} }
String OS_Android::get_unique_id() const { String OS_Android::get_unique_id() const {
if (get_unique_id_func) String unique_id = godot_io_java->get_unique_id();
return get_unique_id_func(); if (unique_id != "")
return unique_id;
return OS::get_unique_id(); return OS::get_unique_id();
} }
Error OS_Android::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { Error OS_Android::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
// FIXME: Add support for volume, audio and subtitle tracks // FIXME: Add support for volume, audio and subtitle tracks
if (video_play_func)
video_play_func(p_path); godot_io_java->play_video(p_path);
return OK; return OK;
} }
bool OS_Android::native_video_is_playing() const { bool OS_Android::native_video_is_playing() const {
if (video_is_playing_func)
return video_is_playing_func(); return godot_io_java->is_video_playing();
return false;
} }
void OS_Android::native_video_pause() { void OS_Android::native_video_pause() {
if (video_pause_func)
video_pause_func(); godot_io_java->pause_video();
} }
String OS_Android::get_system_dir(SystemDir p_dir) const { String OS_Android::get_system_dir(SystemDir p_dir) const {
if (get_system_dir_func) return godot_io_java->get_system_dir(p_dir);
return get_system_dir_func(p_dir);
return String(".");
} }
void OS_Android::native_video_stop() { void OS_Android::native_video_stop() {
if (video_stop_func)
video_stop_func(); godot_io_java->stop_video();
} }
void OS_Android::set_context_is_16_bits(bool p_is_16) { void OS_Android::set_context_is_16_bits(bool p_is_16) {
@ -719,7 +723,7 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
return false; return false;
} }
OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, SetClipboardFunc p_set_clipboard_func, GetClipboardFunc p_get_clipboard_func, RequestPermissionFunc p_request_permission, bool p_use_apk_expansion) { OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion) {
use_apk_expansion = p_use_apk_expansion; use_apk_expansion = p_use_apk_expansion;
default_videomode.width = 800; default_videomode.width = 800;
@ -727,38 +731,13 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
default_videomode.fullscreen = true; default_videomode.fullscreen = true;
default_videomode.resizable = false; default_videomode.resizable = false;
gfx_init_func = p_gfx_init_func;
gfx_init_ud = p_gfx_init_ud;
main_loop = NULL; main_loop = NULL;
gl_extensions = NULL; gl_extensions = NULL;
//rasterizer = NULL; //rasterizer = NULL;
use_gl2 = false; use_gl2 = false;
open_uri_func = p_open_uri_func; godot_java = p_godot_java;
get_user_data_dir_func = p_get_user_data_dir_func; godot_io_java = p_godot_io_java;
get_locale_func = p_get_locale_func;
get_model_func = p_get_model_func;
get_screen_dpi_func = p_get_screen_dpi_func;
get_unique_id_func = p_get_unique_id;
get_system_dir_func = p_get_sdir_func;
get_gl_version_code_func = p_get_gl_version_func;
video_play_func = p_video_play_func;
video_is_playing_func = p_video_is_playing_func;
video_pause_func = p_video_pause_func;
video_stop_func = p_video_stop_func;
show_virtual_keyboard_func = p_show_vk;
hide_virtual_keyboard_func = p_hide_vk;
get_virtual_keyboard_height_func = p_vk_height_func;
set_clipboard_func = p_set_clipboard_func;
get_clipboard_func = p_get_clipboard_func;
set_screen_orientation_func = p_screen_orient;
set_keep_screen_on_func = p_set_keep_screen_on_func;
alert_func = p_alert_func;
request_permission_func = p_request_permission;
Vector<Logger *> loggers; Vector<Logger *> loggers;
loggers.push_back(memnew(AndroidLogger)); loggers.push_back(memnew(AndroidLogger));

View file

@ -41,29 +41,8 @@
#include "servers/audio_server.h" #include "servers/audio_server.h"
#include "servers/visual/rasterizer.h" #include "servers/visual/rasterizer.h"
typedef void (*GFXInitFunc)(void *ud, bool gl2); class GodotJavaWrapper;
typedef int (*OpenURIFunc)(const String &); class GodotIOJavaWrapper;
typedef String (*GetUserDataDirFunc)();
typedef String (*GetLocaleFunc)();
typedef void (*SetClipboardFunc)(const String &);
typedef String (*GetClipboardFunc)();
typedef String (*GetModelFunc)();
typedef int (*GetScreenDPIFunc)();
typedef String (*GetUniqueIDFunc)();
typedef void (*ShowVirtualKeyboardFunc)(const String &);
typedef void (*HideVirtualKeyboardFunc)();
typedef void (*SetScreenOrientationFunc)(int);
typedef String (*GetSystemDirFunc)(int);
typedef int (*GetGLVersionCodeFunc)();
typedef void (*VideoPlayFunc)(const String &);
typedef bool (*VideoIsPlayingFunc)();
typedef void (*VideoPauseFunc)();
typedef void (*VideoStopFunc)();
typedef void (*SetKeepScreenOnFunc)(bool p_enabled);
typedef void (*AlertFunc)(const String &, const String &);
typedef int (*VirtualKeyboardHeightFunc)();
typedef bool (*RequestPermissionFunc)(const String &);
class OS_Android : public OS_Unix { class OS_Android : public OS_Unix {
public: public:
@ -91,9 +70,6 @@ public:
private: private:
Vector<TouchPos> touch; Vector<TouchPos> touch;
GFXInitFunc gfx_init_func;
void *gfx_init_ud;
bool use_gl2; bool use_gl2;
bool use_apk_expansion; bool use_apk_expansion;
@ -112,30 +88,11 @@ private:
VideoMode default_videomode; VideoMode default_videomode;
MainLoop *main_loop; MainLoop *main_loop;
OpenURIFunc open_uri_func; GodotJavaWrapper *godot_java;
GetUserDataDirFunc get_user_data_dir_func; GodotIOJavaWrapper *godot_io_java;
GetLocaleFunc get_locale_func;
SetClipboardFunc set_clipboard_func;
GetClipboardFunc get_clipboard_func;
GetModelFunc get_model_func;
GetScreenDPIFunc get_screen_dpi_func;
ShowVirtualKeyboardFunc show_virtual_keyboard_func;
HideVirtualKeyboardFunc hide_virtual_keyboard_func;
VirtualKeyboardHeightFunc get_virtual_keyboard_height_func;
SetScreenOrientationFunc set_screen_orientation_func;
GetUniqueIDFunc get_unique_id_func;
GetSystemDirFunc get_system_dir_func;
GetGLVersionCodeFunc get_gl_version_code_func;
VideoPlayFunc video_play_func; //PowerAndroid *power_manager_func;
VideoIsPlayingFunc video_is_playing_func;
VideoPauseFunc video_pause_func;
VideoStopFunc video_stop_func;
SetKeepScreenOnFunc set_keep_screen_on_func;
AlertFunc alert_func;
RequestPermissionFunc request_permission_func;
//PowerAndroid *power_manager;
int video_driver_index; int video_driver_index;
public: public:
@ -159,6 +116,8 @@ public:
typedef int64_t ProcessID; typedef int64_t ProcessID;
static OS *get_singleton(); static OS *get_singleton();
GodotJavaWrapper *get_godot_java();
GodotIOJavaWrapper *get_godot_io_java();
virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual bool request_permission(const String &p_name); virtual bool request_permission(const String &p_name);
@ -241,7 +200,7 @@ public:
void joy_connection_changed(int p_device, bool p_connected, String p_name); void joy_connection_changed(int p_device, bool p_connected, String p_name);
virtual bool _check_internal_feature_support(const String &p_feature); virtual bool _check_internal_feature_support(const String &p_feature);
OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, SetClipboardFunc p_set_clipboard, GetClipboardFunc p_get_clipboard, RequestPermissionFunc p_request_permission, bool p_use_apk_expansion); OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);
~OS_Android(); ~OS_Android();
}; };