From faa861f1ab705ca637837488321f9f682b4f7f35 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 28 Feb 2026 16:04:16 +0100 Subject: Android: Fix Wii Remote connection crashes Users are reporting a crash at the point where WiimoteAndroid::IORead tries to use m_java_wiimote_payload. This commit solves the problem by making m_java_wiimote_payload a global reference. The code for setting up m_java_wiimote_payload has also been moved to the constructor just because that way it's impossible for it to run twice. (If the code as written were to run a second time, the old global reference would be leaked. ConnectInternal should only run once, so this is just to be on the safe side.) Fixes https://bugs.dolphin-emu.org/issues/13960. --- Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp b/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp index bdc0a6fc42..11045ca204 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp @@ -58,11 +58,25 @@ auto WiimoteScannerAndroid::FindAttachedWiimotes() -> FindResults WiimoteAndroid::WiimoteAndroid(int index) : Wiimote(), m_mayflash_index(index) { + auto* const env = IDCache::GetEnvForThread(); + + jfieldID payload_field = env->GetStaticFieldID(s_adapter_class, "wiimotePayload", "[[B"); + jobjectArray payload_object = + reinterpret_cast(env->GetStaticObjectField(s_adapter_class, payload_field)); + jobject java_wiimote_payload = env->GetObjectArrayElement(payload_object, m_mayflash_index); + m_java_wiimote_payload = reinterpret_cast(env->NewGlobalRef(java_wiimote_payload)); + + // Get function pointers + m_input_func = env->GetStaticMethodID(s_adapter_class, "input", "(I)I"); + m_output_func = env->GetStaticMethodID(s_adapter_class, "output", "(I[BI)I"); } WiimoteAndroid::~WiimoteAndroid() { Shutdown(); + + auto* const env = IDCache::GetEnvForThread(); + env->DeleteGlobalRef(m_java_wiimote_payload); } std::string WiimoteAndroid::GetId() const @@ -81,17 +95,6 @@ bool WiimoteAndroid::ConnectInternal() if (IsConnected()) return true; - auto* const env = IDCache::GetEnvForThread(); - - jfieldID payload_field = env->GetStaticFieldID(s_adapter_class, "wiimotePayload", "[[B"); - jobjectArray payload_object = - reinterpret_cast(env->GetStaticObjectField(s_adapter_class, payload_field)); - m_java_wiimote_payload = (jbyteArray)env->GetObjectArrayElement(payload_object, m_mayflash_index); - - // Get function pointers - m_input_func = env->GetStaticMethodID(s_adapter_class, "input", "(I)I"); - m_output_func = env->GetStaticMethodID(s_adapter_class, "output", "(I[BI)I"); - // Test a write to see if a remote is actually connected to the DolphinBar. constexpr u8 report[] = {WR_SET_REPORT | BT_OUTPUT, u8(WiimoteCommon::OutputReportID::RequestStatus), 0}; -- cgit v1.2.3 From 5a914e52477a9bd82824ee2453492255cc6304ce Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 28 Feb 2026 16:13:36 +0100 Subject: Android: Use DeleteLocalRef more in WiimoteAndroid Doesn't matter a lot, but we're supposed to do this to be nice citizens. --- Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp b/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp index 11045ca204..e82f389a21 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp @@ -66,6 +66,9 @@ WiimoteAndroid::WiimoteAndroid(int index) : Wiimote(), m_mayflash_index(index) jobject java_wiimote_payload = env->GetObjectArrayElement(payload_object, m_mayflash_index); m_java_wiimote_payload = reinterpret_cast(env->NewGlobalRef(java_wiimote_payload)); + env->DeleteLocalRef(payload_object); + env->DeleteLocalRef(java_wiimote_payload); + // Get function pointers m_input_func = env->GetStaticMethodID(s_adapter_class, "input", "(I)I"); m_output_func = env->GetStaticMethodID(s_adapter_class, "output", "(I[BI)I"); @@ -152,5 +155,6 @@ void InitAdapterClass() JNIEnv* env = IDCache::GetEnvForThread(); jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/WiimoteAdapter"); s_adapter_class = reinterpret_cast(env->NewGlobalRef(adapter_class)); + env->DeleteLocalRef(adapter_class); } } // namespace WiimoteReal -- cgit v1.2.3