Thanks for the fix of `JavaClassWrapper` in https://github.com/godotengine/godot/pull/96182 and the changes in the previous commit, this introduces an `AndroidRuntime` plugin which provides GDScript access to the Android runtime capabilities.
This allows developers to get access to various Android capabilities without the need of a plugin.
For example, the following logic can be used to check whether the device supports vibration:
```
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
print("Checking if the device supports vibration")
var vibrator_service = android_runtime.getApplicationContext().getSystemService("vibrator")
if vibrator_service:
if vibrator_service.hasVibrator():
print("Vibration is supported on device!")
else:
printerr("Vibration is not supported on device")
else:
printerr("Unable to retrieve the vibrator service")
else:
printerr("Couldn't find AndroidRuntime singleton")
```
Update the export logic to enable apk generation and signing for Android editor builds
Note: Only legacy builds are supported. Gradle builds are not supported at this point in time.
- Returns an empty list when there's not registered plugins, thus preventing the creation of spurious iterator objects
- Inline `Godot#getRotatedValues(...)` given it only had a single caller. This allows to remove the allocation of a float array on each call and replace it with float variables
- Disable sensor events by default. Sensor events can fired at 10-100s Hz taking cpu and memory resources. Now the use of sensor data is behind a project setting allowing projects that have use of it to enable it, while other projects don't pay the cost for a feature they don't use
- Create a pool of specialized input `Runnable` objects to prevent spurious, unbounded `Runnable` allocations
- Disable showing the boot logo for Android XR projects
- Delete locale references of jni strings
On Android the exit logic goes through `Godot#onDestroy()` who attempts to cleanup the engine using the following code:
```
runOnRenderThread {
GodotLib.ondestroy()
forceQuit()
}
```
The issue however is that by the time we ran this code, the render thread has already been paused (but not yet destroyed), and thus `GodotLib.ondestroy()` and `forceQuit()` which are scheduled on the render thread are not executed.
To address this, we instead explicitly request the render thread to exit and block until it does. As part of it exit logic, the render thread has been updated to properly destroy and clean the native instance of the Godot engine, resolving the issue.
Long press is used to simulate right-click events for finger touch and stylus. The previous logic also caused it to trigger for mouse input, which is not needed since the user can instead use the mouse right click button.
This update disables long press as right click events for mouse input.
- Add support for dispatching input on the render thread (UI thread is the current default) when `input_buffering` and `accumulated_input` are disabled. At the expense of latency, this helps prevent 'heavy' applications / games from blocking the UI thread (the default behavior) which may cause the application to ANR.
- Remove GLSurfaceView logic causing the UI thread to wait on the GL thread during lifecycle events. The removed logic would cause the UI thread to ANR when the GL thread is blocked.
- Fix invalid detection of mouse input. Prioritize using the event tool type to detect the type of the event, and only use the event source as fallback.
- Ensure that pressure and tilt information is passed for touch drag events
- Consolidate logic and remove redundant methods
- Improve the logic to detect when external hardware keyboards are connected to the device
Replace the use of WindowInsetsAnimation with WindowInsetsAnimationCompat; the former was only introdcued in api 30 and caused a crash on older versions of Android.
Fixes https://github.com/godotengine/godot/issues/91773
Once sensor listeners are registered, onSensorChanged() (and subsequently
getRotatedValues()) gets called multiple times per socond. Obtaining
WindowManager on each of those calls is superfluous and can be avoided
by extracting it to a lazy class val. getRotatedValue() can also be
called before checking sensor type, and used for each one of them,
resulting in less code repetition.
This PR prevents potential NPEs, and follows Kotlin conventions more closely
by replacing the unsafe !! operator with safe ?. (or ?.let) (usually
!! would only be used very rarely, and with a good reason - there is one
place left in this PR where !! makes sense), and by replacing Java style
'if (x != null)' with Kotlin's '?.'