From dc2d9905f3f8c3913921248fd5fcf8c873c89264 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Wed, 19 Apr 2023 16:30:22 -0500 Subject: [PATCH] Check exceptions in BBQ and SC JNI code Updates the following callback wrappers to crash the client when exceptions are thrown: * TransactionCommittedListenerWrapper * TransactionHangCallbackWrapper * TrustedPresentationCallbackWrapper * WindowInfosReportedListenerWrapper This prevents misleading error messages where a later JNI call fails due to a pending Java exception. Bug: 278526360 Bug: 278573545 Test: presubmits Change-Id: I796e46640b6d1ab43152de9040cbc4b7f25addb9 --- core/jni/android_graphics_BLASTBufferQueue.cpp | 14 ++++++++------ core/jni/android_view_SurfaceControl.cpp | 3 +++ core/jni/core_jni_helpers.h | 9 +++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp index 55aa7117221ea..4474d4cabacba 100644 --- a/core/jni/android_graphics_BLASTBufferQueue.cpp +++ b/core/jni/android_graphics_BLASTBufferQueue.cpp @@ -52,7 +52,7 @@ static JNIEnv* getenv(JavaVM* vm) { return env; } - struct { +struct { jmethodID onTransactionHang; } gTransactionHangCallback; @@ -72,12 +72,14 @@ public: } void onTransactionHang(const std::string& reason) { - if (mTransactionHangObject) { - JNIEnv* env = getenv(mVm); - ScopedLocalRef jReason(env, env->NewStringUTF(reason.c_str())); - getenv(mVm)->CallVoidMethod(mTransactionHangObject, - gTransactionHangCallback.onTransactionHang, jReason.get()); + if (!mTransactionHangObject) { + return; } + JNIEnv* env = getenv(mVm); + ScopedLocalRef jReason(env, env->NewStringUTF(reason.c_str())); + getenv(mVm)->CallVoidMethod(mTransactionHangObject, + gTransactionHangCallback.onTransactionHang, jReason.get()); + DieIfException(env, "Uncaught exception in TransactionHangCallback."); } private: diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index e42c6f107e6dd..8e96ac1363701 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -285,6 +285,7 @@ public: JNIEnv* env = getenv(); env->CallVoidMethod(mTransactionCommittedListenerObject, gTransactionCommittedListenerClassInfo.onTransactionCommitted); + DieIfException(env, "Uncaught exception in TransactionCommittedListener."); } static void transactionCallbackThunk(void* context, nsecs_t /*latchTime*/, @@ -325,6 +326,7 @@ public: binder::Status onWindowInfosReported() override { JNIEnv* env = getenv(); env->CallVoidMethod(mListener, gRunnableClassInfo.run); + DieIfException(env, "Uncaught exception in WindowInfosReportedListener."); return binder::Status::ok(); } @@ -356,6 +358,7 @@ public: env->CallVoidMethod(mTrustedPresentationCallback, gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged, inTrustedPresentationState); + DieIfException(env, "Uncaught exception in TrustedPresentationCallback."); } void addCallbackRef(const sp& callbackRef) { diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h index b85a42529fb6b..210dc895d674f 100644 --- a/core/jni/core_jni_helpers.h +++ b/core/jni/core_jni_helpers.h @@ -134,6 +134,15 @@ static inline JNIEnv* GetOrAttachJNIEnvironment(JavaVM* jvm, jint version = JNI_ return env; } +static inline void DieIfException(JNIEnv* env, const char* message) { + if (env->ExceptionCheck()) { + jnihelp::ExpandableString summary; + jnihelp::ExpandableStringInitialize(&summary); + jnihelp::GetStackTraceOrSummary(env, nullptr, &summary); + LOG_ALWAYS_FATAL("%s\n%s", message, summary.data); + } +} + } // namespace android #endif // CORE_JNI_HELPERS