From bd28520bd5c46f10178b1bade3eb56cc6ef0a048 Mon Sep 17 00:00:00 2001 From: melekr Date: Fri, 28 Nov 2025 18:24:29 -0500 Subject: [PATCH] Android: resolve APK path for crash handler on split APK / OBB builds Add GetApkPathForCrashHandler() to resolve APK path --- Runtime/Native/Android/NativeClient.cs | 88 ++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/Runtime/Native/Android/NativeClient.cs b/Runtime/Native/Android/NativeClient.cs index c4b235d5..88afed5b 100644 --- a/Runtime/Native/Android/NativeClient.cs +++ b/Runtime/Native/Android/NativeClient.cs @@ -218,6 +218,83 @@ private string GuessNativeDirectoryPath() } } + /// + /// Resolve the path to the base APK that contains the Backtrace Java classes. + /// + private static string GetApkPathForCrashHandler() + { + String applicationDataPath = Application.dataPath; +#if UNITY_ANDROID && !UNITY_EDITOR + try + { + using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + { + if (unityPlayer == null) + { + return applicationDataPath; + } + + using (AndroidJavaObject activity = unityPlayer.GetStatic("currentActivity")) + { + if (activity == null) + { + return applicationDataPath; + } + + using (AndroidJavaObject context = activity.Call("getApplicationContext")) + { + if (context != null) + { + using (AndroidJavaObject applicationInfo = context.Call("getApplicationInfo")) + { + if (applicationInfo != null) + { + String sourceDir = applicationInfo.Get("sourceDir"); + if (!String.IsNullOrEmpty(sourceDir)) + { + return sourceDir; + } + } + } + + using (AndroidJavaObject packageManager = context.Call("getPackageManager")) + { + if (packageManager != null) + { + String packageName = context.Call("getPackageName"); + if (!String.IsNullOrEmpty(packageName)) + { + using (AndroidJavaObject pmApplicationInfo = packageManager.Call("getApplicationInfo", packageName, 0)) + { + if (pmApplicationInfo != null) + { + String pmSourceDir = pmApplicationInfo.Get("sourceDir"); + if (!String.IsNullOrEmpty(pmSourceDir)) + { + return pmSourceDir; + } + } + } + } + } + } + } + } + } + } + } + catch (Exception e) + { + Debug.LogWarning(String.Format("Backtrace native crash handler: failed to resolve APK path, " + "falling back to Application.dataPath. Reason: {0}", e.Message)); + } + + return applicationDataPath; +#else + // Editor/non‑Android + return applicationDataPath; +#endif + } + /// /// Start crashpad process to handle native Android crashes /// @@ -287,7 +364,10 @@ private void HandleNativeCrashes(IDictionary backtraceAttributes return; } - CaptureNativeCrashes = InitializeJavaCrashHandler(minidumpUrl, databasePath, backtraceAttributes["device.abi"], libDirectory, attachments); + // Resolve the APK path + var apkPath = GetApkPathForCrashHandler(); + + CaptureNativeCrashes = InitializeJavaCrashHandler(minidumpUrl, databasePath, backtraceAttributes["device.abi"], libDirectory, apkPath, attachments); if (!CaptureNativeCrashes) { @@ -311,7 +391,7 @@ private void HandleNativeCrashes(IDictionary backtraceAttributes AddAttribute(AndroidJNI.NewStringUTF(ErrorTypeAttribute), AndroidJNI.NewStringUTF(CrashType)); } - private bool InitializeJavaCrashHandler(String minidumpUrl, String databasePath, String deviceAbi, String nativeDirectory, IEnumerable attachments) { + private bool InitializeJavaCrashHandler(String minidumpUrl, String databasePath, String deviceAbi, String nativeDirectory, String apkPath, IEnumerable attachments) { if (String.IsNullOrEmpty(deviceAbi)) { Debug.LogWarning("Cannot determine device ABI"); return false; @@ -326,12 +406,12 @@ private bool InitializeJavaCrashHandler(String minidumpUrl, String databasePath, // verify if the library is already extracted var backtraceNativeLibraryPath = Path.Combine(nativeDirectory, _nativeLibraryName); if (!File.Exists(backtraceNativeLibraryPath)) { - backtraceNativeLibraryPath = string.Format("{0}!/lib/{1}/{2}", Application.dataPath, deviceAbi, _nativeLibraryName); + backtraceNativeLibraryPath = string.Format("{0}!/lib/{1}/{2}", apkPath, deviceAbi, _nativeLibraryName); } // prepare native crash handler environment variables List environmentVariables = new List () { - string.Format("CLASSPATH={0}", Application.dataPath), + string.Format("CLASSPATH={0}", apkPath), string.Format("BACKTRACE_UNITY_CRASH_HANDLER={0}", backtraceNativeLibraryPath), string.Format("LD_LIBRARY_PATH={0}", string.Join(":", nativeDirectory, Directory.GetParent(nativeDirectory), GetLibrarySystemPath(), "/data/local")), "ANDROID_DATA=/data"