using System; using System.Runtime.CompilerServices; using UnityEngine; internal static class JniHelper { public static void CallStaticSafe(this AndroidJavaClass clazz, string methodName, params object[] args) { PushLocalFrame(); try { clazz.CallStatic(methodName, args); } finally { PopLocalFrame(); } } public static void CallStaticSafe(this AndroidJavaObject jo, string methodName, params object[] args) { PushLocalFrame(); try { jo.CallStatic(methodName, args); } finally { PopLocalFrame(); } } private static bool DoesHaveLocalReferenceCount(int count) { if (AndroidJNI.PushLocalFrame(count) == 0) { AndroidJNI.PopLocalFrame(IntPtr.Zero); return true; } AndroidJNI.ExceptionClear(); return false; } public static int GetFreeLocalReferenceCount() { int num2 = 0; int count = 1; while (DoesHaveLocalReferenceCount(count) && (count < 0x40000000)) { count *= 2; } while (count > 0) { int num4 = num2 + count; if (DoesHaveLocalReferenceCount(num4)) { num2 = num4; } count /= 2; } return num2; } public static void PopLocalFrame() { AndroidJNI.PopLocalFrame(IntPtr.Zero); } public static IntPtr PopLocalFrame(IntPtr result) { return AndroidJNI.PopLocalFrame(result); } public static void PushLocalFrame() { PushLocalFrame(0x80); } public static void PushLocalFrame(int capacity) { if (AndroidJNI.PushLocalFrame(capacity) != 0) { AndroidJNI.ExceptionClear(); if (AndroidJNI.PushLocalFrame(0) != 0) { throw new InsufficientMemoryException(string.Format("Failed to allocate memory for {0} local JNI references", capacity)); } } } }