summaryrefslogtreecommitdiffstats
path: root/platform/android/java
diff options
context:
space:
mode:
authorFredia Huya-Kouadio <fhuyakou@gmail.com>2024-07-03 22:32:47 -0700
committerFredia Huya-Kouadio <fhuyakou@gmail.com>2024-07-04 02:46:11 -0700
commitc6a23a7a7d3f0747ccfdc11a56fc04f57feb867f (patch)
treebd865fc0e13441ded11e07bb59709a1c5331c494 /platform/android/java
parente6448ca0aa050b71cb40d9658b7233b8ec7f7382 (diff)
downloadredot-engine-c6a23a7a7d3f0747ccfdc11a56fc04f57feb867f.tar.gz
Fix crashes reported by the Google Play Console
Diffstat (limited to 'platform/android/java')
-rw-r--r--platform/android/java/app/config.gradle2
-rw-r--r--platform/android/java/editor/build.gradle2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.kt74
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java7
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt11
6 files changed, 56 insertions, 42 deletions
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 01759a1b2f..eb9ad9de05 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -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.
diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle
index 55fe2a22fe..37f68d295a 100644
--- a/platform/android/java/editor/build.gradle
+++ b/platform/android/java/editor/build.gradle
@@ -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"
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
index 290be727ab..2bd5e2b315 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
@@ -86,15 +86,14 @@ class Godot(private val context: Context) : SensorEventListener {
private val TAG = Godot::class.java.simpleName
}
- private val windowManager: WindowManager by lazy {
- requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager
- }
+ private val windowManager: WindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ private val mSensorManager: SensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
+ private val mClipboard: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+ private val vibratorService: Vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+
private val pluginRegistry: GodotPluginRegistry by lazy {
GodotPluginRegistry.getPluginRegistry()
}
- private val mSensorManager: SensorManager by lazy {
- requireActivity().getSystemService(Context.SENSOR_SERVICE) as SensorManager
- }
private val mAccelerometer: Sensor? by lazy {
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
}
@@ -107,9 +106,6 @@ class Godot(private val context: Context) : SensorEventListener {
private val mGyroscope: Sensor? by lazy {
mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
}
- private val mClipboard: ClipboardManager by lazy {
- requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
- }
private val uiChangeListener = View.OnSystemUiVisibilityChangeListener { visibility: Int ->
if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
@@ -323,13 +319,15 @@ class Godot(private val context: Context) : SensorEventListener {
return false
}
- if (expansionPackPath.isNotEmpty()) {
- commandLine.add("--main-pack")
- commandLine.add(expansionPackPath)
- }
- val activity = requireActivity()
- if (!nativeLayerInitializeCompleted) {
- nativeLayerInitializeCompleted = GodotLib.initialize(
+ beginBenchmarkMeasure("Startup", "Godot::onInitNativeLayer")
+ try {
+ if (expansionPackPath.isNotEmpty()) {
+ commandLine.add("--main-pack")
+ commandLine.add(expansionPackPath)
+ }
+ val activity = requireActivity()
+ if (!nativeLayerInitializeCompleted) {
+ nativeLayerInitializeCompleted = GodotLib.initialize(
activity,
this,
activity.assets,
@@ -338,15 +336,17 @@ class Godot(private val context: Context) : SensorEventListener {
directoryAccessHandler,
fileAccessHandler,
useApkExpansion,
- )
- }
+ )
+ }
- if (nativeLayerInitializeCompleted && !nativeLayerSetupCompleted) {
- nativeLayerSetupCompleted = GodotLib.setup(commandLine.toTypedArray(), tts)
- if (!nativeLayerSetupCompleted) {
- Log.e(TAG, "Unable to setup the Godot engine! Aborting...")
- alert(R.string.error_engine_setup_message, R.string.text_error_title, this::forceQuit)
+ if (nativeLayerInitializeCompleted && !nativeLayerSetupCompleted) {
+ nativeLayerSetupCompleted = GodotLib.setup(commandLine.toTypedArray(), tts)
+ if (!nativeLayerSetupCompleted) {
+ throw IllegalStateException("Unable to setup the Godot engine! Aborting...")
+ }
}
+ } finally {
+ endBenchmarkMeasure("Startup", "Godot::onInitNativeLayer")
}
return isNativeInitialized()
}
@@ -370,6 +370,7 @@ class Godot(private val context: Context) : SensorEventListener {
throw IllegalStateException("onInitNativeLayer() must be invoked successfully prior to initializing the render view")
}
+ beginBenchmarkMeasure("Startup", "Godot::onInitRenderView")
try {
val activity: Activity = host.activity
containerLayout = providedContainerLayout
@@ -392,8 +393,7 @@ class Godot(private val context: Context) : SensorEventListener {
containerLayout?.addView(editText)
renderView = if (usesVulkan()) {
if (!meetsVulkanRequirements(activity.packageManager)) {
- alert(R.string.error_missing_vulkan_requirements_message, R.string.text_error_title, this::forceQuit)
- return null
+ throw IllegalStateException(activity.getString(R.string.error_missing_vulkan_requirements_message))
}
GodotVulkanRenderView(host, this)
} else {
@@ -482,6 +482,8 @@ class Godot(private val context: Context) : SensorEventListener {
containerLayout?.removeAllViews()
containerLayout = null
}
+
+ endBenchmarkMeasure("Startup", "Godot::onInitRenderView")
}
return containerLayout
}
@@ -609,13 +611,17 @@ class Godot(private val context: Context) : SensorEventListener {
// These properties are defined after Godot setup completion, so we retrieve them here.
val longPressEnabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/enable_long_press_as_right_click"))
val panScaleEnabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/enable_pan_and_scale_gestures"))
- val rotaryInputAxis = java.lang.Integer.parseInt(GodotLib.getGlobal("input_devices/pointing/android/rotary_input_scroll_axis"))
+ val rotaryInputAxisValue = GodotLib.getGlobal("input_devices/pointing/android/rotary_input_scroll_axis")
runOnUiThread {
renderView?.inputHandler?.apply {
enableLongPress(longPressEnabled)
enablePanningAndScalingGestures(panScaleEnabled)
- setRotaryInputAxis(rotaryInputAxis)
+ try {
+ setRotaryInputAxis(Integer.parseInt(rotaryInputAxisValue))
+ } catch (e: NumberFormatException) {
+ Log.w(TAG, e)
+ }
}
}
@@ -646,12 +652,7 @@ class Godot(private val context: Context) : SensorEventListener {
decorView.setOnSystemUiVisibilityChangeListener(uiChangeListener)
}
- @Keep
- private fun alert(message: String, title: String) {
- alert(message, title, null)
- }
-
- private fun alert(
+ fun alert(
@StringRes messageResId: Int,
@StringRes titleResId: Int,
okCallback: Runnable?
@@ -660,7 +661,9 @@ class Godot(private val context: Context) : SensorEventListener {
alert(res.getString(messageResId), res.getString(titleResId), okCallback)
}
- private fun alert(message: String, title: String, okCallback: Runnable?) {
+ @JvmOverloads
+ @Keep
+ fun alert(message: String, title: String, okCallback: Runnable? = null) {
val activity: Activity = getActivity() ?: return
runOnUiThread {
val builder = AlertDialog.Builder(activity)
@@ -770,7 +773,7 @@ class Godot(private val context: Context) : SensorEventListener {
mClipboard.setPrimaryClip(clip)
}
- private fun forceQuit() {
+ fun forceQuit() {
forceQuit(0)
}
@@ -881,7 +884,6 @@ class Godot(private val context: Context) : SensorEventListener {
@Keep
private fun vibrate(durationMs: Int, amplitude: Int) {
if (durationMs > 0 && requestPermission("VIBRATE")) {
- val vibratorService = getActivity()?.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator? ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (amplitude <= -1) {
vibratorService.vibrate(
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java b/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java
index a323045e1b..1612ddd0b3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java
@@ -42,6 +42,7 @@ import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Messenger;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -203,6 +204,12 @@ public class GodotFragment extends Fragment implements IDownloaderClient, GodotH
if (godotContainerLayout == null) {
throw new IllegalStateException("Unable to initialize engine render view");
}
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Engine initialization failed", e);
+ final String errorMessage = TextUtils.isEmpty(e.getMessage())
+ ? getString(R.string.error_engine_setup_message)
+ : e.getMessage();
+ godot.alert(errorMessage, getString(R.string.text_error_title), godot::forceQuit);
} catch (IllegalArgumentException ignored) {
final Activity activity = getActivity();
Intent notifierIntent = new Intent(activity, activity.getClass());
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 4b51bd778d..219631284a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -121,7 +121,7 @@ public class GodotIO {
activity.startActivity(intent);
return 0;
- } catch (ActivityNotFoundException e) {
+ } catch (Exception e) {
Log.e(TAG, "Unable to open uri " + uriString, e);
return 1;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt b/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt
index 69748c0a8d..d39f2309b8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/BenchmarkUtils.kt
@@ -81,7 +81,8 @@ fun beginBenchmarkMeasure(scope: String, label: String) {
*
* * Note: Only enabled on 'editorDev' build variant.
*/
-fun endBenchmarkMeasure(scope: String, label: String) {
+@JvmOverloads
+fun endBenchmarkMeasure(scope: String, label: String, dumpBenchmark: Boolean = false) {
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") {
return
}
@@ -93,6 +94,10 @@ fun endBenchmarkMeasure(scope: String, label: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Trace.endAsyncSection("[$scope] $label", 0)
}
+
+ if (dumpBenchmark) {
+ dumpBenchmark()
+ }
}
/**
@@ -102,11 +107,11 @@ fun endBenchmarkMeasure(scope: String, label: String) {
* * Note: Only enabled on 'editorDev' build variant.
*/
@JvmOverloads
-fun dumpBenchmark(fileAccessHandler: FileAccessHandler?, filepath: String? = benchmarkFile) {
+fun dumpBenchmark(fileAccessHandler: FileAccessHandler? = null, filepath: String? = benchmarkFile) {
if (BuildConfig.FLAVOR != "editor" || BuildConfig.BUILD_TYPE != "dev") {
return
}
- if (!useBenchmark) {
+ if (!useBenchmark || benchmarkTracker.isEmpty()) {
return
}