Skip to content

Commit

Permalink
Merge pull request #93933 from m4gr3d/anr_and_crash_bug_fixes
Browse files Browse the repository at this point in the history
Fix crashes and ANRs reported by the Google Play Console
  • Loading branch information
akien-mga committed Jul 4, 2024
2 parents f9a58be + 6b6428d commit 8455b33
Show file tree
Hide file tree
Showing 19 changed files with 298 additions and 172 deletions.
6 changes: 6 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,12 @@
Enabling this can greatly improve the responsiveness to input, specially in devices that need to run multiple physics frames per visible (process) frame, because they can't run at the target frame rate.
[b]Note:[/b] Currently implemented only on Android.
</member>
<member name="input_devices/buffering/android/use_accumulated_input" type="bool" setter="" getter="" default="true">
If [code]true[/code], multiple input events will be accumulated into a single input event when possible.
</member>
<member name="input_devices/buffering/android/use_input_buffering" type="bool" setter="" getter="" default="true">
If [code]true[/code], input events will be buffered prior to being dispatched.
</member>
<member name="input_devices/compatibility/legacy_just_pressed_behavior" type="bool" setter="" getter="" default="false">
If [code]true[/code], [method Input.is_action_just_pressed] and [method Input.is_action_just_released] will only return [code]true[/code] if the action is still in the respective state, i.e. an action that is pressed [i]and[/i] released on the same frame will be missed.
If [code]false[/code], no input will be lost.
Expand Down
5 changes: 5 additions & 0 deletions editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/vsync_mode", 1, "Disabled,Enabled,Adaptive,Mailbox")
EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/update_continuously", false, "")

#ifdef ANDROID_ENABLED
EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/android/use_accumulated_input", true, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/android/use_input_buffering", true, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
#endif

// Inspector
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/inspector/max_array_dictionary_items_per_page", 20, "10,100,1")
EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/inspector/show_low_level_opentype_features", false, "")
Expand Down
24 changes: 13 additions & 11 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,13 +909,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph

// Benchmark tracking must be done after `OS::get_singleton()->initialize()` as on some
// platforms, it's used to set up the time utilities.
OS::get_singleton()->benchmark_begin_measure("Startup", "Total");
OS::get_singleton()->benchmark_begin_measure("Startup", "Setup");
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Setup");

engine = memnew(Engine);

MAIN_PRINT("Main: Initialize CORE");
OS::get_singleton()->benchmark_begin_measure("Startup", "Core");

register_core_types();
register_core_driver_types();
Expand Down Expand Up @@ -2453,8 +2451,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Thread::release_main_thread(); // If setup2() is called from another thread, that one will become main thread, so preventively release this one.
set_current_thread_safe_for_nodes(false);

OS::get_singleton()->benchmark_end_measure("Startup", "Core");

#if defined(STEAMAPI_ENABLED)
if (editor || project_manager) {
steam_tracker = memnew(SteamTracker);
Expand All @@ -2465,7 +2461,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
return setup2();
}

OS::get_singleton()->benchmark_end_measure("Startup", "Setup");
OS::get_singleton()->benchmark_end_measure("Startup", "Main::Setup");
return OK;

error:
Expand Down Expand Up @@ -2519,7 +2515,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}

OS::get_singleton()->benchmark_end_measure("Startup", "Core");
OS::get_singleton()->benchmark_end_measure("Startup", "Setup");
OS::get_singleton()->benchmark_end_measure("Startup", "Main::Setup");

#if defined(STEAMAPI_ENABLED)
if (steam_tracker) {
Expand Down Expand Up @@ -2553,6 +2549,8 @@ Error _parse_resource_dummy(void *p_data, VariantParser::Stream *p_stream, Ref<R
}

Error Main::setup2(bool p_show_boot_logo) {
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Setup2");

Thread::make_main_thread(); // Make whatever thread call this the main thread.
set_current_thread_safe_for_nodes(true);

Expand Down Expand Up @@ -2941,6 +2939,8 @@ Error Main::setup2(bool p_show_boot_logo) {
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_mouse_from_touch", true)));
}

GLOBAL_DEF("input_devices/buffering/android/use_accumulated_input", true);
GLOBAL_DEF("input_devices/buffering/android/use_input_buffering", true);
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false);
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false);
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);
Expand Down Expand Up @@ -3149,7 +3149,7 @@ Error Main::setup2(bool p_show_boot_logo) {
print_verbose("EDITOR API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
MAIN_PRINT("Main: Done");

OS::get_singleton()->benchmark_end_measure("Startup", "Setup");
OS::get_singleton()->benchmark_end_measure("Startup", "Main::Setup2");

return OK;
}
Expand Down Expand Up @@ -3230,6 +3230,8 @@ static MainTimerSync main_timer_sync;
// and should move on to `OS::run`, and EXIT_FAILURE otherwise for
// an early exit with that error code.
int Main::start() {
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Start");

ERR_FAIL_COND_V(!_start_success, false);

bool has_icon = false;
Expand Down Expand Up @@ -3953,7 +3955,7 @@ int Main::start() {
}
}

OS::get_singleton()->benchmark_end_measure("Startup", "Total");
OS::get_singleton()->benchmark_end_measure("Startup", "Main::Start");
OS::get_singleton()->benchmark_dump();

return EXIT_SUCCESS;
Expand Down Expand Up @@ -4221,7 +4223,7 @@ void Main::force_redraw() {
* The order matters as some of those steps are linked with each other.
*/
void Main::cleanup(bool p_force) {
OS::get_singleton()->benchmark_begin_measure("Shutdown", "Total");
OS::get_singleton()->benchmark_begin_measure("Shutdown", "Main::Cleanup");
if (!p_force) {
ERR_FAIL_COND(!_start_success);
}
Expand Down Expand Up @@ -4379,7 +4381,7 @@ void Main::cleanup(bool p_force) {

unregister_core_types();

OS::get_singleton()->benchmark_end_measure("Shutdown", "Total");
OS::get_singleton()->benchmark_end_measure("Shutdown", "Main::Cleanup");
OS::get_singleton()->benchmark_dump();

OS::get_singleton()->finalize_core();
Expand Down
4 changes: 4 additions & 0 deletions platform/android/java/app/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
android:hasFragileUserData="false"
android:requestLegacyExternalStorage="false"
tools:ignore="GoogleAppIndexingWarning" >
<profileable
android:shell="true"
android:enabled="true"
tools:targetApi="29" />

<!-- Records the version of the Godot editor used for building -->
<meta-data
Expand Down
2 changes: 1 addition & 1 deletion platform/android/java/app/config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ext.versions = [
targetSdk : 34,
buildTools : '34.0.0',
kotlinVersion : '1.9.20',
fragmentVersion : '1.6.2',
fragmentVersion : '1.7.1',
nexusPublishVersion: '1.3.0',
javaVersion : JavaVersion.VERSION_17,
// Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
Expand Down
2 changes: 1 addition & 1 deletion platform/android/java/editor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies {
implementation "androidx.fragment:fragment:$versions.fragmentVersion"
implementation project(":lib")

implementation "androidx.window:window:1.2.0"
implementation "androidx.window:window:1.3.0"
implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,18 @@ open class GodotEditor : GodotActivity() {
val longPressEnabled = enableLongPressGestures()
val panScaleEnabled = enablePanAndScaleGestures()

val useInputBuffering = useInputBuffering()
val useAccumulatedInput = useAccumulatedInput()
GodotLib.updateInputDispatchSettings(useAccumulatedInput, useInputBuffering)

checkForProjectPermissionsToEnable()

runOnUiThread {
// Enable long press, panning and scaling gestures
godotFragment?.godot?.renderView?.inputHandler?.apply {
enableLongPress(longPressEnabled)
enablePanningAndScalingGestures(panScaleEnabled)
enableInputDispatchToRenderThread(!useInputBuffering && !useAccumulatedInput)
}
}
}
Expand Down Expand Up @@ -274,6 +279,13 @@ open class GodotEditor : GodotActivity() {
protected open fun enablePanAndScaleGestures() =
java.lang.Boolean.parseBoolean(GodotLib.getEditorSetting("interface/touchscreen/enable_pan_and_scale_gestures"))

/**
* Use input buffering for the Godot Android editor.
*/
protected open fun useInputBuffering() = java.lang.Boolean.parseBoolean(GodotLib.getEditorSetting("interface/editor/android/use_input_buffering"))

protected open fun useAccumulatedInput() = java.lang.Boolean.parseBoolean(GodotLib.getEditorSetting("interface/editor/android/use_accumulated_input"))

/**
* Whether we should launch the new godot instance in an adjacent window
* @see https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

package org.godotengine.editor

import org.godotengine.godot.GodotLib

/**
* Drives the 'run project' window of the Godot Editor.
*/
Expand All @@ -39,9 +41,13 @@ class GodotGame : GodotEditor() {

override fun overrideOrientationRequest() = false

override fun enableLongPressGestures() = false
override fun enableLongPressGestures() = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/enable_long_press_as_right_click"))

override fun enablePanAndScaleGestures() = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/enable_pan_and_scale_gestures"))

override fun useInputBuffering() = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/buffering/android/use_input_buffering"))

override fun enablePanAndScaleGestures() = false
override fun useAccumulatedInput() = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/buffering/android/use_accumulated_input"))

override fun checkForProjectPermissionsToEnable() {
// Nothing to do.. by the time we get here, the project permissions will have already
Expand Down
Loading

0 comments on commit 8455b33

Please sign in to comment.