summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/android_input_handler.cpp19
-rw-r--r--platform/android/android_input_handler.h2
-rw-r--r--platform/android/android_keys_utils.cpp38
-rw-r--r--platform/android/android_keys_utils.h3
-rw-r--r--platform/android/display_server_android.cpp13
-rw-r--r--platform/android/java/editor/src/dev/res/values/strings.xml2
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt50
-rw-r--r--platform/android/java/editor/src/main/res/values/strings.xml2
-rw-r--r--platform/android/java/lib/res/values/strings.xml2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java30
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java38
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotHost.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java2
-rw-r--r--platform/android/java_godot_lib_jni.cpp4
-rw-r--r--platform/android/java_godot_lib_jni.h2
-rw-r--r--platform/android/java_godot_wrapper.cpp19
-rw-r--r--platform/android/java_godot_wrapper.h4
-rw-r--r--platform/android/os_android.cpp16
-rw-r--r--platform/android/os_android.h3
24 files changed, 188 insertions, 122 deletions
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index e3f93086dc..17903b3965 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -56,7 +56,7 @@ void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> e
ev->set_ctrl_pressed(control_mem);
}
-void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed) {
+void AndroidInputHandler::process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed) {
static char32_t prev_wc = 0;
char32_t unicode = p_unicode;
if ((p_unicode & 0xfffffc00) == 0xd800) {
@@ -81,8 +81,18 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod
Key physical_keycode = godot_code_from_android_code(p_physical_keycode);
Key keycode = physical_keycode;
- if (p_keycode != 0) {
- keycode = godot_code_from_unicode(p_keycode);
+ if (unicode == '\b') { // 0x08
+ keycode = Key::BACKSPACE;
+ } else if (unicode == '\t') { // 0x09
+ keycode = Key::TAB;
+ } else if (unicode == '\n') { // 0x0A
+ keycode = Key::ENTER;
+ } else if (unicode == 0x1B) {
+ keycode = Key::ESCAPE;
+ } else if (unicode == 0x1F) {
+ keycode = Key::KEY_DELETE;
+ } else {
+ keycode = fix_keycode(unicode, physical_keycode);
}
switch (physical_keycode) {
@@ -104,7 +114,8 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod
ev->set_keycode(keycode);
ev->set_physical_keycode(physical_keycode);
- ev->set_unicode(unicode);
+ ev->set_key_label(fix_key_label(p_key_label, keycode));
+ ev->set_unicode(fix_unicode(unicode));
ev->set_pressed(p_pressed);
_set_key_modifier_state(ev);
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index 34259efd81..6e53dcfc89 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -97,7 +97,7 @@ public:
void process_magnify(Point2 p_pos, float p_factor);
void process_pan(Point2 p_pos, Vector2 p_delta);
void process_joy_event(JoypadEvent p_event);
- void process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed);
+ void process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed);
};
#endif // ANDROID_INPUT_HANDLER_H
diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp
index 0dc2d19cdd..f50437e82a 100644
--- a/platform/android/android_keys_utils.cpp
+++ b/platform/android/android_keys_utils.cpp
@@ -38,41 +38,3 @@ Key godot_code_from_android_code(unsigned int p_code) {
}
return Key::UNKNOWN;
}
-
-Key godot_code_from_unicode(unsigned int p_code) {
- unsigned int code = p_code;
- if (code > 0xFF) {
- return Key::UNKNOWN;
- }
- // Known control codes.
- if (code == '\b') { // 0x08
- return Key::BACKSPACE;
- }
- if (code == '\t') { // 0x09
- return Key::TAB;
- }
- if (code == '\n') { // 0x0A
- return Key::ENTER;
- }
- if (code == 0x1B) {
- return Key::ESCAPE;
- }
- if (code == 0x1F) {
- return Key::KEY_DELETE;
- }
- // Unknown control codes.
- if (code <= 0x1F || (code >= 0x80 && code <= 0x9F)) {
- return Key::UNKNOWN;
- }
- // Convert to uppercase.
- if (code >= 'a' && code <= 'z') { // 0x61 - 0x7A
- code -= ('a' - 'A');
- }
- if (code >= u'à' && code <= u'ö') { // 0xE0 - 0xF6
- code -= (u'à' - u'À'); // 0xE0 - 0xC0
- }
- if (code >= u'ø' && code <= u'þ') { // 0xF8 - 0xFF
- code -= (u'ø' - u'Ø'); // 0xF8 - 0xD8
- }
- return Key(code);
-}
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index 33e7929278..3a587dd680 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -165,13 +165,14 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_NUMPAD_DOT, Key::KP_PERIOD }, // (158) Numeric keypad '.' key (for decimals or digit grouping).
{ AKEYCODE_NUMPAD_ENTER, Key::KP_ENTER }, // (160) Numeric keypad Enter key.
{ AKEYCODE_VOLUME_MUTE, Key::VOLUMEMUTE }, // (164) Volume Mute key.
+ { AKEYCODE_EISU, Key::JIS_EISU }, // (212) JIS EISU key.
{ AKEYCODE_YEN, Key::YEN }, // (216) Japanese Yen key.
+ { AKEYCODE_KANA, Key::JIS_KANA }, // (218) JIS KANA key.
{ AKEYCODE_HELP, Key::HELP }, // (259) Help key.
{ AKEYCODE_REFRESH, Key::REFRESH }, // (285) Refresh key.
{ AKEYCODE_MAX, Key::UNKNOWN }
};
Key godot_code_from_android_code(unsigned int p_code);
-Key godot_code_from_unicode(unsigned int p_code);
#endif // ANDROID_KEYS_UTILS_H
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 6b3bdb7fe6..3fcb926f86 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -212,7 +212,18 @@ float DisplayServerAndroid::screen_get_scale(int p_screen) const {
GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
ERR_FAIL_NULL_V(godot_io_java, 1.0f);
- return godot_io_java->get_scaled_density();
+ float screen_scale = godot_io_java->get_scaled_density();
+
+ // Update the scale to avoid cropping.
+ Size2i screen_size = screen_get_size(p_screen);
+ if (screen_size != Size2i()) {
+ float width_scale = screen_size.width / (float)OS_Android::DEFAULT_WINDOW_WIDTH;
+ float height_scale = screen_size.height / (float)OS_Android::DEFAULT_WINDOW_HEIGHT;
+ screen_scale = MIN(screen_scale, MIN(width_scale, height_scale));
+ }
+
+ print_line("Selected screen scale: ", screen_scale);
+ return screen_scale;
}
float DisplayServerAndroid::screen_get_refresh_rate(int p_screen) const {
diff --git a/platform/android/java/editor/src/dev/res/values/strings.xml b/platform/android/java/editor/src/dev/res/values/strings.xml
index 45fae3fd39..215f2c7d0a 100644
--- a/platform/android/java/editor/src/dev/res/values/strings.xml
+++ b/platform/android/java/editor/src/dev/res/values/strings.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="godot_editor_name_string">Godot Editor 4.x (dev)</string>
+ <string name="godot_editor_name_string">Godot Editor 4 (dev)</string>
</resources>
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
index f848089aa8..71385315ae 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
@@ -31,12 +31,11 @@
package org.godotengine.editor
import android.Manifest
+import android.app.ActivityManager
+import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
-import android.os.Build
-import android.os.Bundle
-import android.os.Debug
-import android.os.Environment
+import android.os.*
import android.util.Log
import android.widget.Toast
import androidx.window.layout.WindowMetricsCalculator
@@ -64,11 +63,18 @@ open class GodotEditor : FullScreenGodotApp() {
private const val COMMAND_LINE_PARAMS = "command_line_params"
+ private const val EDITOR_ID = 777
private const val EDITOR_ARG = "--editor"
private const val EDITOR_ARG_SHORT = "-e"
+ private const val EDITOR_PROCESS_NAME_SUFFIX = ":GodotEditor"
+ private const val GAME_ID = 667
+ private const val GAME_PROCESS_NAME_SUFFIX = ":GodotGame"
+
+ private const val PROJECT_MANAGER_ID = 555
private const val PROJECT_MANAGER_ARG = "--project-manager"
private const val PROJECT_MANAGER_ARG_SHORT = "-p"
+ private const val PROJECT_MANAGER_PROCESS_NAME_SUFFIX = ":GodotProjectManager"
}
private val commandLineParams = ArrayList<String>()
@@ -102,9 +108,10 @@ open class GodotEditor : FullScreenGodotApp() {
override fun getCommandLine() = commandLineParams
- override fun onNewGodotInstanceRequested(args: Array<String>) {
+ override fun onNewGodotInstanceRequested(args: Array<String>): Int {
// Parse the arguments to figure out which activity to start.
var targetClass: Class<*> = GodotGame::class.java
+ var instanceId = GAME_ID
// Whether we should launch the new godot instance in an adjacent window
// https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
@@ -115,12 +122,14 @@ open class GodotEditor : FullScreenGodotApp() {
if (EDITOR_ARG == arg || EDITOR_ARG_SHORT == arg) {
targetClass = GodotEditor::class.java
launchAdjacent = false
+ instanceId = EDITOR_ID
break
}
if (PROJECT_MANAGER_ARG == arg || PROJECT_MANAGER_ARG_SHORT == arg) {
targetClass = GodotProjectManager::class.java
launchAdjacent = false
+ instanceId = PROJECT_MANAGER_ID
break
}
}
@@ -139,6 +148,37 @@ open class GodotEditor : FullScreenGodotApp() {
Log.d(TAG, "Starting $targetClass")
startActivity(newInstance)
}
+ return instanceId
+ }
+
+ override fun onGodotForceQuit(godotInstanceId: Int): Boolean {
+ val processNameSuffix = when (godotInstanceId) {
+ GAME_ID -> {
+ GAME_PROCESS_NAME_SUFFIX
+ }
+ EDITOR_ID -> {
+ EDITOR_PROCESS_NAME_SUFFIX
+ }
+ PROJECT_MANAGER_ID -> {
+ PROJECT_MANAGER_PROCESS_NAME_SUFFIX
+ }
+ else -> ""
+ }
+ if (processNameSuffix.isBlank()) {
+ return false
+ }
+
+ val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ val runningProcesses = activityManager.runningAppProcesses
+ for (runningProcess in runningProcesses) {
+ if (runningProcess.processName.endsWith(processNameSuffix)) {
+ Log.v(TAG, "Killing Godot process ${runningProcess.processName}")
+ Process.killProcess(runningProcess.pid)
+ return true
+ }
+ }
+
+ return false
}
// Get the screen's density scale
diff --git a/platform/android/java/editor/src/main/res/values/strings.xml b/platform/android/java/editor/src/main/res/values/strings.xml
index 837a5d62e1..216d02d9c7 100644
--- a/platform/android/java/editor/src/main/res/values/strings.xml
+++ b/platform/android/java/editor/src/main/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="godot_editor_name_string">Godot Editor 4.x</string>
+ <string name="godot_editor_name_string">Godot Editor 4</string>
<string name="denied_storage_permission_error_msg">Missing storage access permission!</string>
</resources>
diff --git a/platform/android/java/lib/res/values/strings.xml b/platform/android/java/lib/res/values/strings.xml
index f5a4ab1071..7efac4ce71 100644
--- a/platform/android/java/lib/res/values/strings.xml
+++ b/platform/android/java/lib/res/values/strings.xml
@@ -48,7 +48,7 @@
<string name="state_failed_unlicensed">Download failed because you may not have purchased this app</string>
<string name="state_failed_fetching_url">Download failed because the resources could not be found</string>
<string name="state_failed_sdcard_full">Download failed because the external storage is full</string>
- <string name="state_failed_cancelled">Download cancelled</string>
+ <string name="state_failed_cancelled">Download canceled</string>
<string name="state_failed">Download failed</string>
<string name="kilobytes_per_second">%1$s KB/s</string>
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index 863e67f1e9..65032d6a68 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -74,28 +74,36 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
public void onDestroy() {
Log.v(TAG, "Destroying Godot app...");
super.onDestroy();
- onGodotForceQuit(godotFragment);
+ terminateGodotInstance(godotFragment);
}
@Override
public final void onGodotForceQuit(Godot instance) {
+ runOnUiThread(() -> {
+ terminateGodotInstance(instance);
+ });
+ }
+
+ private void terminateGodotInstance(Godot instance) {
if (instance == godotFragment) {
Log.v(TAG, "Force quitting Godot instance");
- ProcessPhoenix.forceQuit(this);
+ ProcessPhoenix.forceQuit(FullScreenGodotApp.this);
}
}
@Override
public final void onGodotRestartRequested(Godot instance) {
- if (instance == godotFragment) {
- // It's very hard to properly de-initialize Godot on Android to restart the game
- // from scratch. Therefore, we need to kill the whole app process and relaunch it.
- //
- // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including
- // releasing and reloading native libs or resetting their state somehow and clearing statics).
- Log.v(TAG, "Restarting Godot instance...");
- ProcessPhoenix.triggerRebirth(this);
- }
+ runOnUiThread(() -> {
+ if (instance == godotFragment) {
+ // It's very hard to properly de-initialize Godot on Android to restart the game
+ // from scratch. Therefore, we need to kill the whole app process and relaunch it.
+ //
+ // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including
+ // releasing and reloading native libs or resetting their state somehow and clearing statics).
+ Log.v(TAG, "Restarting Godot instance...");
+ ProcessPhoenix.triggerRebirth(FullScreenGodotApp.this);
+ }
+ });
}
@Override
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 905db13c85..50263bc392 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -348,11 +348,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public void restart() {
- runOnUiThread(() -> {
- if (godotHost != null) {
- godotHost.onGodotRestartRequested(this);
- }
- });
+ if (godotHost != null) {
+ godotHost.onGodotRestartRequested(this);
+ }
}
public void alert(final String message, final String title) {
@@ -889,11 +887,20 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private void forceQuit() {
// TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
// native Godot components that is started in Godot#onVideoInit.
- runOnUiThread(() -> {
- if (godotHost != null) {
- godotHost.onGodotForceQuit(this);
- }
- });
+ forceQuit(0);
+ }
+
+ @Keep
+ private boolean forceQuit(int instanceId) {
+ if (godotHost == null) {
+ return false;
+ }
+ if (instanceId == 0) {
+ godotHost.onGodotForceQuit(this);
+ return true;
+ } else {
+ return godotHost.onGodotForceQuit(instanceId);
+ }
}
private boolean obbIsCorrupted(String f, String main_pack_md5) {
@@ -1052,11 +1059,10 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
@Keep
- private void createNewGodotInstance(String[] args) {
- runOnUiThread(() -> {
- if (godotHost != null) {
- godotHost.onNewGodotInstanceRequested(args);
- }
- });
+ private int createNewGodotInstance(String[] args) {
+ if (godotHost != null) {
+ return godotHost.onNewGodotInstanceRequested(args);
+ }
+ return 0;
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
index 256d04e3a5..7700b9b628 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
@@ -55,21 +55,35 @@ public interface GodotHost {
default void onGodotMainLoopStarted() {}
/**
- * Invoked on the UI thread as the last step of the Godot instance clean up phase.
+ * Invoked on the render thread to terminate the given Godot instance.
*/
default void onGodotForceQuit(Godot instance) {}
/**
- * Invoked on the UI thread when the Godot instance wants to be restarted. It's up to the host
+ * Invoked on the render thread to terminate the Godot instance with the given id.
+ * @param godotInstanceId id of the Godot instance to terminate. See {@code onNewGodotInstanceRequested}
+ *
+ * @return true if successful, false otherwise.
+ */
+ default boolean onGodotForceQuit(int godotInstanceId) {
+ return false;
+ }
+
+ /**
+ * Invoked on the render thread when the Godot instance wants to be restarted. It's up to the host
* to perform the appropriate action(s).
*/
default void onGodotRestartRequested(Godot instance) {}
/**
- * Invoked on the UI thread when a new Godot instance is requested. It's up to the host to
+ * Invoked on the render thread when a new Godot instance is requested. It's up to the host to
* perform the appropriate action(s).
*
* @param args Arguments used to initialize the new instance.
+ *
+ * @return the id of the new instance. See {@code onGodotForceQuit}
*/
- default void onNewGodotInstanceRequested(String[] args) {}
+ default int onNewGodotInstanceRequested(String[] args) {
+ return 0;
+ }
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index aca0c4381b..41d06a6458 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -150,7 +150,6 @@ public class GodotIO {
} else {
selectedScaledDensity = 0.75f;
}
- Log.d(TAG, "Selected scaled density: " + selectedScaledDensity);
return selectedScaledDensity;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 31b512d2dd..75a01dc787 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -148,7 +148,7 @@ public class GodotLib {
/**
* Forward regular key events.
*/
- public static native void key(int p_keycode, int p_physical_keycode, int p_unicode, boolean p_pressed);
+ public static native void key(int p_physical_keycode, int p_unicode, int p_key_label, boolean p_pressed);
/**
* Forward game device's key events.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index f2bd3e28e6..cedbbfb7c3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -129,12 +129,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
} else {
// getKeyCode(): The physical key that was pressed.
- // Godot's keycodes match the ASCII codes, so for single byte unicode characters,
- // we can use the unmodified unicode character to determine Godot's keycode.
- final int keycode = event.getUnicodeChar(0);
final int physical_keycode = event.getKeyCode();
final int unicode = event.getUnicodeChar();
- GodotLib.key(keycode, physical_keycode, unicode, false);
+ final int key_label = event.getDisplayLabel();
+ GodotLib.key(physical_keycode, unicode, key_label, false);
};
return true;
@@ -166,10 +164,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
GodotLib.joybutton(godotJoyId, button, true);
}
} else {
- final int keycode = event.getUnicodeChar(0);
final int physical_keycode = event.getKeyCode();
final int unicode = event.getUnicodeChar();
- GodotLib.key(keycode, physical_keycode, unicode, true);
+ final int key_label = event.getDisplayLabel();
+ GodotLib.key(physical_keycode, unicode, key_label, true);
}
return true;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index fdfe20f32b..7b628e25ed 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -93,8 +93,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
@Override
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
for (int i = 0; i < count; ++i) {
- GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, true);
- GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, false);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, 0, false);
if (mHasSelection) {
mHasSelection = false;
@@ -110,13 +110,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
newChars[i - start] = pCharSequence.charAt(i);
}
for (int i = 0; i < count; ++i) {
- int key = newChars[i];
- if ((key == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) {
+ final int character = newChars[i];
+ if ((character == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) {
// Return keys are handled through action events
continue;
}
- GodotLib.key(key, 0, key, true);
- GodotLib.key(key, 0, key, false);
+ GodotLib.key(0, character, 0, true);
+ GodotLib.key(0, character, 0, false);
}
}
@@ -126,17 +126,17 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
final String characters = pKeyEvent.getCharacters();
for (int i = 0; i < characters.length(); i++) {
- final int ch = characters.codePointAt(i);
- GodotLib.key(ch, 0, ch, true);
- GodotLib.key(ch, 0, ch, false);
+ final int character = characters.codePointAt(i);
+ GodotLib.key(0, character, 0, true);
+ GodotLib.key(0, character, 0, false);
}
}
if (pActionID == EditorInfo.IME_ACTION_DONE) {
// Enter key has been pressed
mRenderView.queueOnRenderThread(() -> {
- GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, true);
- GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, false);
+ GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, 0, false);
});
mRenderView.getView().requestFocus();
return true;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
index 9649b0aecc..b9b7ebac6e 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
@@ -64,7 +64,7 @@ internal class AssetsDirectoryAccess(context: Context) : DirectoryAccessHandler.
override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0
override fun dirOpen(path: String): Int {
- val assetsPath = getAssetsPath(path) ?: return INVALID_DIR_ID
+ val assetsPath = getAssetsPath(path)
try {
val files = assetManager.list(assetsPath) ?: return INVALID_DIR_ID
// Empty directories don't get added to the 'assets' directory, so
@@ -99,7 +99,7 @@ internal class AssetsDirectoryAccess(context: Context) : DirectoryAccessHandler.
}
override fun fileExists(path: String): Boolean {
- val assetsPath = getAssetsPath(path) ?: return false
+ val assetsPath = getAssetsPath(path)
try {
val files = assetManager.list(assetsPath) ?: return false
// Empty directories don't get added to the 'assets' directory, so
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java b/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java
index 2cc37b627a..3ee3478fcb 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java
@@ -120,7 +120,7 @@ public final class ProcessPhoenix extends Activity {
/**
* Checks if the current process is a temporary Phoenix Process.
- * This can be used to avoid initialisation of unused resources or to prevent running code that
+ * This can be used to avoid initialization of unused resources or to prevent running code that
* is not multi-process ready.
*
* @return true if the current process is a temporary Phoenix Process
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index e6cdd7932a..1ee1cccb82 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -382,11 +382,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(
}
// Called on the UI thread
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_physical_keycode, jint p_unicode, jint p_key_label, jboolean p_pressed) {
if (step.get() <= 0) {
return;
}
- input_handler->process_key_event(p_keycode, p_physical_keycode, p_unicode, p_pressed);
+ input_handler->process_key_event(p_physical_keycode, p_unicode, p_key_label, p_pressed);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) {
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index 3f07a8cfe1..0020ddffd2 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -49,7 +49,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchMouseEvent(JN
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jboolean p_double_tap);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnify(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_factor);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_pan(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_delta_x, jfloat p_delta_y);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_physical_keycode, jint p_unicode, jint p_key_label, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y);
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index 03548d11f6..9d9d087896 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -60,7 +60,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
// get some Godot method pointers...
_on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()Z");
_restart = p_env->GetMethodID(godot_class, "restart", "()V");
- _finish = p_env->GetMethodID(godot_class, "forceQuit", "()V");
+ _finish = p_env->GetMethodID(godot_class, "forceQuit", "(I)Z");
_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V");
_alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
_get_GLES_version_code = p_env->GetMethodID(godot_class, "getGLESVersionCode", "()I");
@@ -77,7 +77,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
_get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;");
_on_godot_setup_completed = p_env->GetMethodID(godot_class, "onGodotSetupCompleted", "()V");
_on_godot_main_loop_started = p_env->GetMethodID(godot_class, "onGodotMainLoopStarted", "()V");
- _create_new_godot_instance = p_env->GetMethodID(godot_class, "createNewGodotInstance", "([Ljava/lang/String;)V");
+ _create_new_godot_instance = p_env->GetMethodID(godot_class, "createNewGodotInstance", "([Ljava/lang/String;)I");
_get_render_view = p_env->GetMethodID(godot_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;");
// get some Activity method pointers...
@@ -179,14 +179,15 @@ void GodotJavaWrapper::restart(JNIEnv *p_env) {
}
}
-void GodotJavaWrapper::force_quit(JNIEnv *p_env) {
+bool GodotJavaWrapper::force_quit(JNIEnv *p_env, int p_instance_id) {
if (_finish) {
if (p_env == nullptr) {
p_env = get_jni_env();
}
- ERR_FAIL_NULL(p_env);
- p_env->CallVoidMethod(godot_instance, _finish);
+ ERR_FAIL_NULL_V(p_env, false);
+ return p_env->CallBooleanMethod(godot_instance, _finish, p_instance_id);
}
+ return false;
}
void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) {
@@ -345,14 +346,16 @@ void GodotJavaWrapper::vibrate(int p_duration_ms) {
}
}
-void GodotJavaWrapper::create_new_godot_instance(List<String> args) {
+int GodotJavaWrapper::create_new_godot_instance(List<String> args) {
if (_create_new_godot_instance) {
JNIEnv *env = get_jni_env();
- ERR_FAIL_NULL(env);
+ ERR_FAIL_NULL_V(env, 0);
jobjectArray jargs = env->NewObjectArray(args.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));
for (int i = 0; i < args.size(); i++) {
env->SetObjectArrayElement(jargs, i, env->NewStringUTF(args[i].utf8().get_data()));
}
- env->CallVoidMethod(godot_instance, _create_new_godot_instance, jargs);
+ return env->CallIntMethod(godot_instance, _create_new_godot_instance, jargs);
+ } else {
+ return 0;
}
}
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index 5dad2a3eb9..1bd79584d8 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -85,7 +85,7 @@ public:
void on_godot_setup_completed(JNIEnv *p_env = nullptr);
void on_godot_main_loop_started(JNIEnv *p_env = nullptr);
void restart(JNIEnv *p_env = nullptr);
- void force_quit(JNIEnv *p_env = nullptr);
+ bool force_quit(JNIEnv *p_env = nullptr, int p_instance_id = 0);
void set_keep_screen_on(bool p_enabled);
void alert(const String &p_message, const String &p_title);
int get_gles_version_code();
@@ -103,7 +103,7 @@ public:
bool is_activity_resumed();
void vibrate(int p_duration_ms);
String get_input_fallback_mapping();
- void create_new_godot_instance(List<String> args);
+ int create_new_godot_instance(List<String> args);
};
#endif // JAVA_GODOT_WRAPPER_H
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 942bf0a904..725fea8d54 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -695,8 +695,8 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
}
OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion) {
- display_size.width = 800;
- display_size.height = 600;
+ display_size.width = DEFAULT_WINDOW_WIDTH;
+ display_size.height = DEFAULT_WINDOW_HEIGHT;
use_apk_expansion = p_use_apk_expansion;
@@ -739,9 +739,19 @@ Error OS_Android::create_process(const String &p_path, const List<String> &p_arg
}
Error OS_Android::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
- godot_java->create_new_godot_instance(p_arguments);
+ int instance_id = godot_java->create_new_godot_instance(p_arguments);
+ if (r_child_id) {
+ *r_child_id = instance_id;
+ }
return OK;
}
+Error OS_Android::kill(const ProcessID &p_pid) {
+ if (godot_java->force_quit(nullptr, p_pid)) {
+ return OK;
+ }
+ return OS_Unix::kill(p_pid);
+}
+
OS_Android::~OS_Android() {
}
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 68b6fefe33..53910b1498 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -86,6 +86,8 @@ private:
public:
static const char *ANDROID_EXEC_PATH;
+ static const int DEFAULT_WINDOW_WIDTH = 800;
+ static const int DEFAULT_WINDOW_HEIGHT = 600;
virtual void initialize_core() override;
virtual void initialize() override;
@@ -156,6 +158,7 @@ public:
virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) override;
virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override;
virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
+ virtual Error kill(const ProcessID &p_pid) override;
virtual bool _check_internal_feature_support(const String &p_feature) override;
OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);