mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-18 00:01:45 +00:00
android: thread local env
This commit is contained in:
parent
3132839113
commit
0dec8feadb
6 changed files with 33 additions and 70 deletions
|
@ -29,9 +29,27 @@ static jmethodID s_do_rumble;
|
||||||
|
|
||||||
namespace IDCache
|
namespace IDCache
|
||||||
{
|
{
|
||||||
JavaVM* GetJavaVM()
|
JNIEnv* GetEnvForThread()
|
||||||
{
|
{
|
||||||
return s_java_vm;
|
thread_local static struct OwnedEnv
|
||||||
|
{
|
||||||
|
OwnedEnv()
|
||||||
|
{
|
||||||
|
status = s_java_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
|
||||||
|
if (status == JNI_EDETACHED)
|
||||||
|
s_java_vm->AttachCurrentThread(&env, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
~OwnedEnv()
|
||||||
|
{
|
||||||
|
if (status == JNI_EDETACHED)
|
||||||
|
s_java_vm->DetachCurrentThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
int status;
|
||||||
|
JNIEnv* env = nullptr;
|
||||||
|
} owned;
|
||||||
|
return owned.env;
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass GetNativeLibraryClass()
|
jclass GetNativeLibraryClass()
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace IDCache
|
||||||
{
|
{
|
||||||
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
|
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
|
||||||
|
|
||||||
JavaVM* GetJavaVM();
|
JNIEnv* GetEnvForThread();
|
||||||
|
|
||||||
jclass GetNativeLibraryClass();
|
jclass GetNativeLibraryClass();
|
||||||
jmethodID GetDisplayAlertMsg();
|
jmethodID GetDisplayAlertMsg();
|
||||||
|
|
|
@ -75,17 +75,8 @@ bool s_have_wm_user_stop = false;
|
||||||
void UpdatePointer()
|
void UpdatePointer()
|
||||||
{
|
{
|
||||||
// Update touch pointer
|
// Update touch pointer
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
int get_env_status =
|
|
||||||
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
|
|
||||||
|
|
||||||
if (get_env_status == JNI_EDETACHED)
|
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
|
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetUpdateTouchPointer());
|
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetUpdateTouchPointer());
|
||||||
|
|
||||||
if (get_env_status == JNI_EDETACHED)
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host_NotifyMapLoaded()
|
void Host_NotifyMapLoaded()
|
||||||
|
@ -157,28 +148,19 @@ void Host_UpdateProgressDialog(const char* caption, int position, int total)
|
||||||
|
|
||||||
static bool MsgAlert(const char* caption, const char* text, bool yes_no, MsgType /*style*/)
|
static bool MsgAlert(const char* caption, const char* text, bool yes_no, MsgType /*style*/)
|
||||||
{
|
{
|
||||||
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "%s:%s", caption, text);
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
|
||||||
// Associate the current Thread with the Java VM.
|
|
||||||
JNIEnv* env;
|
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
|
|
||||||
// Execute the Java method.
|
// Execute the Java method.
|
||||||
jboolean result = env->CallStaticBooleanMethod(
|
jboolean result = env->CallStaticBooleanMethod(
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), ToJString(env, caption),
|
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), ToJString(env, caption),
|
||||||
ToJString(env, text), yes_no ? JNI_TRUE : JNI_FALSE);
|
ToJString(env, text), yes_no ? JNI_TRUE : JNI_FALSE);
|
||||||
|
|
||||||
// Must be called before the current thread exits; might as well do it here.
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
|
|
||||||
return result != JNI_FALSE;
|
return result != JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReportSend(std::string endpoint, std::string report)
|
static void ReportSend(std::string endpoint, std::string report)
|
||||||
{
|
{
|
||||||
// Associate the current Thread with the Java VM.
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
JNIEnv* env;
|
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
|
|
||||||
jbyteArray output_array = env->NewByteArray(report.size());
|
jbyteArray output_array = env->NewByteArray(report.size());
|
||||||
jbyte* output = env->GetByteArrayElements(output_array, nullptr);
|
jbyte* output = env->GetByteArrayElements(output_array, nullptr);
|
||||||
|
@ -186,32 +168,17 @@ static void ReportSend(std::string endpoint, std::string report)
|
||||||
env->ReleaseByteArrayElements(output_array, output, 0);
|
env->ReleaseByteArrayElements(output_array, output, 0);
|
||||||
env->CallStaticVoidMethod(IDCache::GetAnalyticsClass(), IDCache::GetSendAnalyticsReport(),
|
env->CallStaticVoidMethod(IDCache::GetAnalyticsClass(), IDCache::GetSendAnalyticsReport(),
|
||||||
ToJString(env, endpoint), output_array);
|
ToJString(env, endpoint), output_array);
|
||||||
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetAnalyticValue(std::string key)
|
static std::string GetAnalyticValue(std::string key)
|
||||||
{
|
{
|
||||||
// Associate the current Thread with the Java VM.
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
JNIEnv* env;
|
|
||||||
bool attached = false;
|
|
||||||
int getEnvStat =
|
|
||||||
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), IDCache::JNI_VERSION);
|
|
||||||
if (getEnvStat == JNI_EDETACHED)
|
|
||||||
{
|
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
attached = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
|
jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
|
||||||
IDCache::GetAnalyticsClass(), IDCache::GetAnalyticsValue(), ToJString(env, key)));
|
IDCache::GetAnalyticsClass(), IDCache::GetAnalyticsValue(), ToJString(env, key)));
|
||||||
|
|
||||||
std::string stdvalue = GetJString(env, value);
|
std::string stdvalue = GetJString(env, value);
|
||||||
|
|
||||||
// Only detach the thread if it wasn't already attached
|
|
||||||
if (attached)
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
|
|
||||||
return stdvalue;
|
return stdvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,7 @@ void WiimoteScannerAndroid::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
|
||||||
|
|
||||||
NOTICE_LOG(WIIMOTE, "Finding Wiimotes");
|
NOTICE_LOG(WIIMOTE, "Finding Wiimotes");
|
||||||
|
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
int get_env_status =
|
|
||||||
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
|
|
||||||
|
|
||||||
if (get_env_status == JNI_EDETACHED)
|
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
|
|
||||||
jmethodID openadapter_func = env->GetStaticMethodID(s_adapter_class, "OpenAdapter", "()Z");
|
jmethodID openadapter_func = env->GetStaticMethodID(s_adapter_class, "OpenAdapter", "()Z");
|
||||||
jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");
|
jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");
|
||||||
|
@ -45,9 +40,6 @@ void WiimoteScannerAndroid::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
|
||||||
for (int i = 0; i < MAX_WIIMOTES; ++i)
|
for (int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
found_wiimotes.emplace_back(new WiimoteAndroid(i));
|
found_wiimotes.emplace_back(new WiimoteAndroid(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_env_status == JNI_EDETACHED)
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WiimoteAndroid::WiimoteAndroid(int index) : Wiimote(), m_mayflash_index(index)
|
WiimoteAndroid::WiimoteAndroid(int index) : Wiimote(), m_mayflash_index(index)
|
||||||
|
@ -62,7 +54,7 @@ WiimoteAndroid::~WiimoteAndroid()
|
||||||
// Connect to a Wiimote with a known address.
|
// Connect to a Wiimote with a known address.
|
||||||
bool WiimoteAndroid::ConnectInternal()
|
bool WiimoteAndroid::ConnectInternal()
|
||||||
{
|
{
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&m_env, nullptr);
|
m_env = IDCache::GetEnvForThread();
|
||||||
|
|
||||||
jfieldID payload_field = m_env->GetStaticFieldID(s_adapter_class, "wiimote_payload", "[[B");
|
jfieldID payload_field = m_env->GetStaticFieldID(s_adapter_class, "wiimote_payload", "[[B");
|
||||||
jobjectArray payload_object =
|
jobjectArray payload_object =
|
||||||
|
@ -81,7 +73,6 @@ bool WiimoteAndroid::ConnectInternal()
|
||||||
|
|
||||||
void WiimoteAndroid::DisconnectInternal()
|
void WiimoteAndroid::DisconnectInternal()
|
||||||
{
|
{
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiimoteAndroid::IsConnected() const
|
bool WiimoteAndroid::IsConnected() const
|
||||||
|
@ -119,9 +110,7 @@ int WiimoteAndroid::IOWrite(u8 const* buf, size_t len)
|
||||||
|
|
||||||
void InitAdapterClass()
|
void InitAdapterClass()
|
||||||
{
|
{
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
|
|
||||||
jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_WiimoteAdapter");
|
jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_WiimoteAdapter");
|
||||||
s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
|
s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,10 +237,8 @@ void Touchscreen::Motor::SetState(ControlState state)
|
||||||
|
|
||||||
void Touchscreen::Motor::Rumble(int padID, double state)
|
void Touchscreen::Motor::Rumble(int padID, double state)
|
||||||
{
|
{
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetDoRumble(), padID, state);
|
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetDoRumble(), padID, state);
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
}
|
}
|
||||||
} // namespace Android
|
} // namespace Android
|
||||||
} // namespace ciface
|
} // namespace ciface
|
||||||
|
|
|
@ -65,8 +65,7 @@ static void ScanThreadFunc()
|
||||||
Common::SetCurrentThreadName("GC Adapter Scanning Thread");
|
Common::SetCurrentThreadName("GC Adapter Scanning Thread");
|
||||||
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread started");
|
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread started");
|
||||||
|
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
|
|
||||||
|
|
||||||
jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");
|
jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");
|
||||||
|
|
||||||
|
@ -77,7 +76,6 @@ static void ScanThreadFunc()
|
||||||
Setup();
|
Setup();
|
||||||
Common::SleepCurrentThread(1000);
|
Common::SleepCurrentThread(1000);
|
||||||
}
|
}
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
|
|
||||||
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread stopped");
|
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread stopped");
|
||||||
}
|
}
|
||||||
|
@ -87,8 +85,7 @@ static void Write()
|
||||||
Common::SetCurrentThreadName("GC Adapter Write Thread");
|
Common::SetCurrentThreadName("GC Adapter Write Thread");
|
||||||
NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread started");
|
NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread started");
|
||||||
|
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
|
|
||||||
jmethodID output_func = env->GetStaticMethodID(s_adapter_class, "Output", "([B)I");
|
jmethodID output_func = env->GetStaticMethodID(s_adapter_class, "Output", "([B)I");
|
||||||
|
|
||||||
while (s_write_adapter_thread_running.IsSet())
|
while (s_write_adapter_thread_running.IsSet())
|
||||||
|
@ -118,8 +115,6 @@ static void Write()
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
|
|
||||||
NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread stopped");
|
NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +124,7 @@ static void Read()
|
||||||
NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread started");
|
NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread started");
|
||||||
|
|
||||||
bool first_read = true;
|
bool first_read = true;
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
|
|
||||||
|
|
||||||
jfieldID payload_field = env->GetStaticFieldID(s_adapter_class, "controller_payload", "[B");
|
jfieldID payload_field = env->GetStaticFieldID(s_adapter_class, "controller_payload", "[B");
|
||||||
jobject payload_object = env->GetStaticObjectField(s_adapter_class, payload_field);
|
jobject payload_object = env->GetStaticObjectField(s_adapter_class, payload_field);
|
||||||
|
@ -184,8 +178,6 @@ static void Read()
|
||||||
s_fd = 0;
|
s_fd = 0;
|
||||||
s_detected = false;
|
s_detected = false;
|
||||||
|
|
||||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
||||||
|
|
||||||
NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread stopped");
|
NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,8 +194,7 @@ void Init()
|
||||||
s_last_init = CoreTiming::GetTicks();
|
s_last_init = CoreTiming::GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv* env;
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
|
|
||||||
|
|
||||||
jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_GCAdapter");
|
jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_GCAdapter");
|
||||||
s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
|
s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue