From 00ba9e8c24cc8bfe78042138a0e81f0e6fe56e9e Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Fri, 24 Jun 2022 16:51:15 +0000 Subject: [PATCH] BBQ: Attach calling thread to jvm if needed When BBQ is destroyed from a native thread created by the app, getEnv fails because the calling thread is not attached to the jvm. To fix this, check the result when getting the env from the jvm and attach the current thread if needed. Test: app in bug doesnt crash when resumed Fixes: 236780458 Change-Id: Ib82b9b372167df60ad230ac309099db9f4a1a1fc --- .../jni/android_graphics_BLASTBufferQueue.cpp | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp index 4af28ea243611..1520ea5c6831f 100644 --- a/core/jni/android_graphics_BLASTBufferQueue.cpp +++ b/core/jni/android_graphics_BLASTBufferQueue.cpp @@ -41,7 +41,12 @@ struct { static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; - if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + auto result = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if (result == JNI_EDETACHED) { + if (vm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) { + LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!"); + } + } else if (result != JNI_OK) { LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm); } return env; @@ -60,28 +65,22 @@ public: } ~TransactionHangCallbackWrapper() { - if (mTransactionHangObject) { - getenv()->DeleteGlobalRef(mTransactionHangObject); + if (mTransactionHangObject != nullptr) { + getenv(mVm)->DeleteGlobalRef(mTransactionHangObject); mTransactionHangObject = nullptr; } } void onTransactionHang(bool isGpuHang) { if (mTransactionHangObject) { - getenv()->CallVoidMethod(mTransactionHangObject, - gTransactionHangCallback.onTransactionHang, isGpuHang); + getenv(mVm)->CallVoidMethod(mTransactionHangObject, + gTransactionHangCallback.onTransactionHang, isGpuHang); } } private: JavaVM* mVm; jobject mTransactionHangObject; - - JNIEnv* getenv() { - JNIEnv* env; - mVm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); - return env; - } }; static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,