diff options
Diffstat (limited to 'platform/android/java')
12 files changed, 176 insertions, 295 deletions
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 0874d77645..00e01884cf 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -21,6 +21,8 @@ android:allowBackup="false" android:icon="@mipmap/icon" android:isGame="true" + android:hasFragileUserData="false" + android:requestLegacyExternalStorage="false" tools:ignore="GoogleAppIndexingWarning" > <!-- Records the version of the Godot editor used for building --> diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 81fc87b7ef..fad64c675f 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,8 +1,8 @@ ext.versions = [ - androidGradlePlugin: '4.2.1', - compileSdk : 29, - minSdk : 18, - targetSdk : 29, + androidGradlePlugin: '4.2.2', + compileSdk : 30, + minSdk : 19, + targetSdk : 30, buildTools : '30.0.3', supportCoreUtils : '1.0.0', kotlinVersion : '1.5.10', diff --git a/platform/android/java/app/gradle.properties b/platform/android/java/app/gradle.properties index 19587bd81f..0ad8e611ca 100644 --- a/platform/android/java/app/gradle.properties +++ b/platform/android/java/app/gradle.properties @@ -4,7 +4,7 @@ # where otherwise specified. # For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html +# https://www.gradle.org/docs/current/userguide/build_environment.html android.enableJetifier=true android.useAndroidX=true @@ -15,7 +15,7 @@ org.gradle.jvmargs=-Xmx4536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# https://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true org.gradle.warning.mode=all diff --git a/platform/android/java/gradle.properties b/platform/android/java/gradle.properties index b51a19a005..5cd94e85d9 100644 --- a/platform/android/java/gradle.properties +++ b/platform/android/java/gradle.properties @@ -7,7 +7,7 @@ # any settings specified in this file. # For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html +# https://www.gradle.org/docs/current/userguide/build_environment.html android.enableJetifier=true android.useAndroidX=true @@ -18,7 +18,7 @@ org.gradle.jvmargs=-Xmx4536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# https://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true org.gradle.warning.mode=all diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java index 2a72c9818d..9aa65fd786 100644 --- a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java +++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java @@ -54,7 +54,7 @@ public class Helpers { /* * Parse the Content-Disposition HTTP Header. The format of the header is defined here: - * http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for + * https://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for * content that is going to be downloaded to the file system. We only support the attachment * type. */ 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 89497d1526..3600706c7c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java +++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java @@ -30,13 +30,15 @@ package org.godotengine.godot; +import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.view.KeyEvent; +import android.util.Log; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; /** @@ -46,6 +48,8 @@ import androidx.fragment.app.FragmentActivity; * within an Android app. */ public abstract class FullScreenGodotApp extends FragmentActivity implements GodotHost { + private static final String TAG = FullScreenGodotApp.class.getSimpleName(); + @Nullable private Godot godotFragment; @@ -53,12 +57,53 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.godot_app_layout); - godotFragment = initGodotInstance(); - if (godotFragment == null) { - throw new IllegalStateException("Godot instance must be non-null."); + + Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.godot_fragment_container); + if (currentFragment instanceof Godot) { + Log.v(TAG, "Reusing existing Godot fragment instance."); + godotFragment = (Godot)currentFragment; + } else { + Log.v(TAG, "Creating new Godot fragment instance."); + godotFragment = initGodotInstance(); + if (godotFragment == null) { + throw new IllegalStateException("Godot instance must be non-null."); + } + + getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + onGodotForceQuit(godotFragment); + } + + @Override + public final void onGodotForceQuit(Godot instance) { + if (instance == godotFragment) { + System.exit(0); } + } - getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss(); + @Override + public final void onGodotRestartRequested(Godot instance) { + if (instance == godotFragment) { + // HACK: + // + // Currently it's very hard to properly deinitialize 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). + // + // Using instrumentation is a way of making the whole app process restart, because Android + // will kill any process of the same package which was already running. + // + Bundle args = new Bundle(); + args.putParcelable("intent", getIntent()); + startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args); + } } @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 8ffa4a9249..896b169953 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -49,7 +49,6 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; @@ -68,15 +67,12 @@ import android.os.Environment; import android.os.Messenger; import android.os.VibrationEffect; import android.os.Vibrator; -import android.provider.Settings.Secure; import android.view.Display; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; -import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import android.widget.Button; @@ -321,7 +317,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC @SuppressLint("MissingPermission") @Keep private void vibrate(int durationMs) { - if (requestPermission("VIBRATE")) { + if (durationMs > 0 && requestPermission("VIBRATE")) { Vibrator v = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE); if (v != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -335,22 +331,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } public void restart() { - // HACK: - // - // Currently it's very hard to properly deinitialize 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). - // - // Using instrumentation is a way of making the whole app process restart, because Android - // will kill any process of the same package which was already running. - // - final Activity activity = getActivity(); - if (activity != null) { - Bundle args = new Bundle(); - args.putParcelable("intent", mCurrentIntent); - activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args); + if (godotHost != null) { + godotHost.onGodotRestartRequested(this); } } @@ -471,7 +453,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC final Activity activity = getActivity(); io = new GodotIO(activity); - io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID); GodotLib.io = io; netUtils = new GodotNetUtils(activity); mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE); @@ -657,8 +638,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC super.onDestroy(); - // 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. forceQuit(); } @@ -842,7 +821,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } private void forceQuit() { - System.exit(0); + // 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. + if (godotHost != null) { + godotHost.onGodotForceQuit(this); + } } private boolean obbIsCorrupted(String f, String main_pack_md5) { 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 317fd13535..7b22895994 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java @@ -53,4 +53,15 @@ public interface GodotHost { * Invoked on the render thread when the Godot main loop has started. */ default void onGodotMainLoopStarted() {} + + /** + * Invoked on the UI thread as the last step of the Godot instance clean up phase. + */ + default void onGodotForceQuit(Godot instance) {} + + /** + * Invoked on the GL 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) {} } 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 66882e8e72..d85d88ec6c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -30,15 +30,19 @@ package org.godotengine.godot; -import org.godotengine.godot.input.*; +import org.godotengine.godot.input.GodotEditText; import android.app.Activity; -import android.content.*; +import android.content.ActivityNotFoundException; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.graphics.Point; import android.net.Uri; -import android.os.*; +import android.os.Build; +import android.os.Environment; +import android.provider.Settings; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseArray; @@ -47,14 +51,16 @@ import android.view.DisplayCutout; import android.view.WindowInsets; import java.io.IOException; -import java.io.InputStream; import java.util.Locale; // Wrapper for native library public class GodotIO { - AssetManager am; - final Activity activity; + private static final String TAG = GodotIO.class.getSimpleName(); + + private final AssetManager am; + private final Activity activity; + private final String uniqueId; GodotEditText edit; final int SCREEN_LANDSCAPE = 0; @@ -66,167 +72,6 @@ public class GodotIO { final int SCREEN_SENSOR = 6; ///////////////////////// - /// FILES - ///////////////////////// - - public int last_file_id = 1; - - static class AssetData { - public boolean eof = false; - public String path; - public InputStream is; - public int len; - public int pos; - } - - SparseArray<AssetData> streams; - - public int file_open(String path, boolean write) { - //System.out.printf("file_open: Attempt to Open %s\n",path); - - //Log.v("MyApp", "TRYING TO OPEN FILE: " + path); - if (write) - return -1; - - AssetData ad = new AssetData(); - - try { - ad.is = am.open(path); - - } catch (Exception e) { - //System.out.printf("Exception on file_open: %s\n",path); - return -1; - } - - try { - ad.len = ad.is.available(); - } catch (Exception e) { - System.out.printf("Exception availabling on file_open: %s\n", path); - return -1; - } - - ad.path = path; - ad.pos = 0; - ++last_file_id; - streams.put(last_file_id, ad); - - return last_file_id; - } - public int file_get_size(int id) { - if (streams.get(id) == null) { - System.out.printf("file_get_size: Invalid file id: %d\n", id); - return -1; - } - - return streams.get(id).len; - } - public void file_seek(int id, int bytes) { - if (streams.get(id) == null) { - System.out.printf("file_get_size: Invalid file id: %d\n", id); - return; - } - //seek sucks - AssetData ad = streams.get(id); - if (bytes > ad.len) - bytes = ad.len; - if (bytes < 0) - bytes = 0; - - try { - if (bytes > (int)ad.pos) { - int todo = bytes - (int)ad.pos; - while (todo > 0) { - todo -= ad.is.skip(todo); - } - ad.pos = bytes; - } else if (bytes < (int)ad.pos) { - ad.is = am.open(ad.path); - - ad.pos = bytes; - int todo = bytes; - while (todo > 0) { - todo -= ad.is.skip(todo); - } - } - - ad.eof = false; - } catch (IOException e) { - System.out.printf("Exception on file_seek: %s\n", e); - return; - } - } - - public int file_tell(int id) { - if (streams.get(id) == null) { - System.out.printf("file_read: Can't tell eof for invalid file id: %d\n", id); - return 0; - } - - AssetData ad = streams.get(id); - return ad.pos; - } - public boolean file_eof(int id) { - if (streams.get(id) == null) { - System.out.printf("file_read: Can't check eof for invalid file id: %d\n", id); - return false; - } - - AssetData ad = streams.get(id); - return ad.eof; - } - - public byte[] file_read(int id, int bytes) { - if (streams.get(id) == null) { - System.out.printf("file_read: Can't read invalid file id: %d\n", id); - return new byte[0]; - } - - AssetData ad = streams.get(id); - - if (ad.pos + bytes > ad.len) { - bytes = ad.len - ad.pos; - ad.eof = true; - } - - if (bytes == 0) { - return new byte[0]; - } - - byte[] buf1 = new byte[bytes]; - int r = 0; - try { - r = ad.is.read(buf1); - } catch (IOException e) { - System.out.printf("Exception on file_read: %s\n", e); - return new byte[bytes]; - } - - if (r == 0) { - return new byte[0]; - } - - ad.pos += r; - - if (r < bytes) { - byte[] buf2 = new byte[r]; - for (int i = 0; i < r; i++) - buf2[i] = buf1[i]; - return buf2; - } else { - return buf1; - } - } - - public void file_close(int id) { - if (streams.get(id) == null) { - System.out.printf("file_close: Can't close invalid file id: %d\n", id); - return; - } - - streams.remove(id); - } - - ///////////////////////// /// DIRECTORIES ///////////////////////// @@ -236,9 +81,9 @@ public class GodotIO { public String path; } - public int last_dir_id = 1; + private int last_dir_id = 1; - SparseArray<AssetDir> dirs; + private final SparseArray<AssetDir> dirs; public int dir_open(String path) { AssetDir ad = new AssetDir(); @@ -257,7 +102,6 @@ public class GodotIO { return -1; } - //System.out.printf("Opened dir: %s\n",path); ++last_dir_id; dirs.put(last_dir_id, ad); @@ -320,9 +164,14 @@ public class GodotIO { GodotIO(Activity p_activity) { am = p_activity.getAssets(); activity = p_activity; - //streams = new HashMap<Integer, AssetData>(); - streams = new SparseArray<>(); dirs = new SparseArray<>(); + String androidId = Settings.Secure.getString(activity.getContentResolver(), + Settings.Secure.ANDROID_ID); + if (androidId == null) { + androidId = ""; + } + + uniqueId = androidId; } ///////////////////////// @@ -331,7 +180,6 @@ public class GodotIO { public int openURI(String p_uri) { try { - Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri); String path = p_uri; String type = ""; if (path.startsWith("/")) { @@ -357,12 +205,12 @@ public class GodotIO { } } - public String getDataDir() { - return activity.getFilesDir().getAbsolutePath(); + public String getCacheDir() { + return activity.getCacheDir().getAbsolutePath(); } - public String getExternalDataDir() { - return activity.getExternalFilesDir(null).getAbsolutePath(); + public String getDataDir() { + return activity.getFilesDir().getAbsolutePath(); } public String getLocale() { @@ -456,51 +304,58 @@ public class GodotIO { public static final int SYSTEM_DIR_PICTURES = 6; public static final int SYSTEM_DIR_RINGTONES = 7; - public String getSystemDir(int idx) { - String what = ""; + public String getSystemDir(int idx, boolean shared_storage) { + String what; switch (idx) { - case SYSTEM_DIR_DESKTOP: { - //what=Environment.DIRECTORY_DOCUMENTS; - what = Environment.DIRECTORY_DOWNLOADS; + case SYSTEM_DIR_DESKTOP: + default: { + what = null; // This leads to the app specific external root directory. } break; + case SYSTEM_DIR_DCIM: { what = Environment.DIRECTORY_DCIM; - } break; + case SYSTEM_DIR_DOCUMENTS: { - what = Environment.DIRECTORY_DOWNLOADS; - //what=Environment.DIRECTORY_DOCUMENTS; + what = Environment.DIRECTORY_DOCUMENTS; } break; + case SYSTEM_DIR_DOWNLOADS: { what = Environment.DIRECTORY_DOWNLOADS; - } break; + case SYSTEM_DIR_MOVIES: { what = Environment.DIRECTORY_MOVIES; - } break; + case SYSTEM_DIR_MUSIC: { what = Environment.DIRECTORY_MUSIC; } break; + case SYSTEM_DIR_PICTURES: { what = Environment.DIRECTORY_PICTURES; } break; + case SYSTEM_DIR_RINGTONES: { what = Environment.DIRECTORY_RINGTONES; - } break; } - if (what.equals("")) - return ""; - return Environment.getExternalStoragePublicDirectory(what).getAbsolutePath(); + if (shared_storage) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + Log.w(TAG, "Shared storage access is limited on Android 10 and higher."); + } + if (TextUtils.isEmpty(what)) { + return Environment.getExternalStorageDirectory().getAbsolutePath(); + } else { + return Environment.getExternalStoragePublicDirectory(what).getAbsolutePath(); + } + } else { + return activity.getExternalFilesDir(what).getAbsolutePath(); + } } - protected static final String PREFS_FILE = "device_id.xml"; - protected static final String PREFS_DEVICE_ID = "device_id"; - - public static String unique_id = ""; public String getUniqueID() { - return unique_id; + return uniqueId; } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java index 1d60c21c60..6b248fd034 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -75,7 +75,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener final int x = Math.round(event.getX()); final int y = Math.round(event.getY()); final int buttonMask = event.getButtonState(); - queueEvent(() -> GodotLib.doubleTap(buttonMask, x, y)); + GodotLib.doubleTap(buttonMask, x, y); return true; } @@ -84,7 +84,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener //Log.i("GodotGesture", "onScroll"); final int x = Math.round(distanceX); final int y = Math.round(distanceY); - queueEvent(() -> GodotLib.scroll(x, y)); + GodotLib.scroll(x, y); return true; } 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 4dc9157545..fc0b84b392 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 @@ -68,10 +68,6 @@ public class GodotInputHandler implements InputDeviceListener { mInputManager.registerInputDeviceListener(this, null); } - private void queueEvent(Runnable task) { - mRenderView.queueOnRenderThread(task); - } - private boolean isKeyEvent_GameDevice(int source) { // Note that keyboards are often (SOURCE_KEYBOARD | SOURCE_DPAD) if (source == (InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD)) @@ -96,13 +92,12 @@ public class GodotInputHandler implements InputDeviceListener { if (mJoystickIds.indexOfKey(deviceId) >= 0) { final int button = getGodotButton(keyCode); final int godotJoyId = mJoystickIds.get(deviceId); - - queueEvent(() -> GodotLib.joybutton(godotJoyId, button, false)); + GodotLib.joybutton(godotJoyId, button, false); } } else { final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); - queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, false)); + GodotLib.key(keyCode, scanCode, chr, false); } return true; @@ -132,13 +127,12 @@ public class GodotInputHandler implements InputDeviceListener { if (mJoystickIds.indexOfKey(deviceId) >= 0) { final int button = getGodotButton(keyCode); final int godotJoyId = mJoystickIds.get(deviceId); - - queueEvent(() -> GodotLib.joybutton(godotJoyId, button, true)); + GodotLib.joybutton(godotJoyId, button, true); } } else { final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); - queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, true)); + GodotLib.key(keyCode, scanCode, chr, true); } return true; @@ -170,18 +164,16 @@ public class GodotInputHandler implements InputDeviceListener { final int action = event.getActionMasked(); final int pointer_idx = event.getPointerId(event.getActionIndex()); - mRenderView.queueOnRenderThread(() -> { - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_MOVE: - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_POINTER_DOWN: { - GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); - } break; - } - }); + switch (action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_POINTER_DOWN: { + GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); + } break; + } } return true; } @@ -205,7 +197,7 @@ public class GodotInputHandler implements InputDeviceListener { // save value to prevent repeats joystick.axesValues.put(axis, value); final int godotAxisIdx = i; - queueEvent(() -> GodotLib.joyaxis(godotJoyId, godotAxisIdx, value)); + GodotLib.joyaxis(godotJoyId, godotAxisIdx, value); } } @@ -215,7 +207,7 @@ public class GodotInputHandler implements InputDeviceListener { if (joystick.hatX != hatX || joystick.hatY != hatY) { joystick.hatX = hatX; joystick.hatY = hatY; - queueEvent(() -> GodotLib.joyhat(godotJoyId, hatX, hatY)); + GodotLib.joyhat(godotJoyId, hatX, hatY); } } return true; @@ -224,7 +216,7 @@ public class GodotInputHandler implements InputDeviceListener { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); - queueEvent(() -> GodotLib.hover(type, x, y)); + GodotLib.hover(type, x, y); return true; } else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) { @@ -316,7 +308,7 @@ public class GodotInputHandler implements InputDeviceListener { } mJoysticksDevices.put(deviceId, joystick); - queueEvent(() -> GodotLib.joyconnectionchanged(id, true, joystick.name)); + GodotLib.joyconnectionchanged(id, true, joystick.name); } @Override @@ -328,8 +320,7 @@ public class GodotInputHandler implements InputDeviceListener { final int godotJoyId = mJoystickIds.get(deviceId); mJoystickIds.delete(deviceId); mJoysticksDevices.delete(deviceId); - - queueEvent(() -> GodotLib.joyconnectionchanged(godotJoyId, false, "")); + GodotLib.joyconnectionchanged(godotJoyId, false, ""); } @Override @@ -418,7 +409,7 @@ public class GodotInputHandler implements InputDeviceListener { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); - queueEvent(() -> GodotLib.hover(type, x, y)); + GodotLib.hover(type, x, y); return true; } case MotionEvent.ACTION_BUTTON_PRESS: @@ -428,7 +419,7 @@ public class GodotInputHandler implements InputDeviceListener { final float y = event.getY(); final int buttonsMask = event.getButtonState(); final int action = event.getAction(); - queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask)); + GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask); return true; } case MotionEvent.ACTION_SCROLL: { @@ -438,7 +429,7 @@ public class GodotInputHandler implements InputDeviceListener { final int action = event.getAction(); final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL); final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL); - queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor)); + GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor); } case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: { 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 020870a110..002a75277d 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 @@ -94,17 +94,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); - mRenderView.queueOnRenderThread(() -> { - for (int i = 0; i < count; ++i) { - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); - - if (mHasSelection) { - mHasSelection = false; - break; - } + for (int i = 0; i < count; ++i) { + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); + + if (mHasSelection) { + mHasSelection = false; + break; } - }); + } } @Override @@ -115,17 +113,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene for (int i = start; i < start + count; ++i) { newChars[i - start] = pCharSequence.charAt(i); } - mRenderView.queueOnRenderThread(() -> { - for (int i = 0; i < count; ++i) { - int key = newChars[i]; - if ((key == '\n') && !mEdit.isMultiline()) { - // Return keys are handled through action events - continue; - } - GodotLib.key(0, 0, key, true); - GodotLib.key(0, 0, key, false); + for (int i = 0; i < count; ++i) { + int key = newChars[i]; + if ((key == '\n') && !mEdit.isMultiline()) { + // Return keys are handled through action events + continue; } - }); + GodotLib.key(0, 0, key, true); + GodotLib.key(0, 0, key, false); + } } @Override @@ -133,13 +129,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene if (mEdit == pTextView && isFullScreenEdit()) { final String characters = pKeyEvent.getCharacters(); - mRenderView.queueOnRenderThread(() -> { - for (int i = 0; i < characters.length(); i++) { - final int ch = characters.codePointAt(i); - GodotLib.key(0, 0, ch, true); - GodotLib.key(0, 0, ch, false); - } - }); + for (int i = 0; i < characters.length(); i++) { + final int ch = characters.codePointAt(i); + GodotLib.key(0, 0, ch, true); + GodotLib.key(0, 0, ch, false); + } } if (pActionID == EditorInfo.IME_ACTION_DONE) { |