diff --git a/core/jni/Android.bp b/core/jni/Android.bp index aa661713b1fe6..4bc946e17d047 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -50,6 +50,7 @@ cc_library_shared { "android_util_XmlBlock.cpp", "android_util_jar_StrictJarFile.cpp", "com_android_internal_util_VirtualRefBasePtr.cpp", + "core_jni_helpers.cpp", ":deviceproductinfoconstants_aidl", ], diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp index 78b403c39a179..cb97698fefea5 100644 --- a/core/jni/android_hardware_SensorManager.cpp +++ b/core/jni/android_hardware_SensorManager.cpp @@ -348,7 +348,7 @@ private: virtual int handleEvent(int fd, int events, void* data) { JNIEnv* env = AndroidRuntime::getJNIEnv(); sp q = reinterpret_cast(data); - ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + ScopedLocalRef receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); ssize_t n; ASensorEvent buffer[16]; diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index c9110d1440186..019e3bd32be9f 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -139,7 +139,7 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla uint32_t count, VsyncEventData vsyncEventData) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + ScopedLocalRef receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); @@ -156,7 +156,7 @@ void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, PhysicalDisp bool connected) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + ScopedLocalRef receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking hotplug handler.", this); env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchHotplug, @@ -171,7 +171,7 @@ void NativeDisplayEventReceiver::dispatchModeChanged(nsecs_t timestamp, Physical int32_t modeId, nsecs_t) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + ScopedLocalRef receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking mode changed handler.", this); env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchModeChanged, @@ -186,7 +186,7 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides( nsecs_t timestamp, PhysicalDisplayId displayId, std::vector overrides) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + ScopedLocalRef receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking FrameRateOverride handler.", this); const auto frameRateOverrideClass = diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index a7ec38f8b0f6c..2b932cb37332a 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -329,7 +329,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, if (!skipCallbacks && !mBatchedInputEventPending && mInputConsumer.hasPendingBatch()) { // There is a pending batch. Come back later. if (!receiverObj.get()) { - receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal)); + receiverObj.reset(GetReferent(env, mReceiverWeakGlobal)); if (!receiverObj.get()) { ALOGW("channel '%s' ~ Receiver object was finalized " "without being disposed.", @@ -358,7 +358,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, if (!skipCallbacks) { if (!receiverObj.get()) { - receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal)); + receiverObj.reset(GetReferent(env, mReceiverWeakGlobal)); if (!receiverObj.get()) { ALOGW("channel '%s' ~ Receiver object was finalized " "without being disposed.", getInputChannelName().c_str()); diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp index 5da273896e296..4bc567abf27ab 100644 --- a/core/jni/android_view_InputEventSender.cpp +++ b/core/jni/android_view_InputEventSender.cpp @@ -200,7 +200,7 @@ status_t NativeInputEventSender::processConsumerResponse(JNIEnv* env) { ALOGD("channel '%s' ~ Receiving finished signals.", getInputChannelName().c_str()); } - ScopedLocalRef senderObj(env, jniGetReferent(env, mSenderWeakGlobal)); + ScopedLocalRef senderObj(env, GetReferent(env, mSenderWeakGlobal)); if (!senderObj.get()) { ALOGW("channel '%s' ~ Sender object was finalized without being disposed.", getInputChannelName().c_str()); diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp index 74bbd7b2cb324..2f9df1fbe9d0e 100644 --- a/core/jni/android_view_InputQueue.cpp +++ b/core/jni/android_view_InputQueue.cpp @@ -136,7 +136,7 @@ void InputQueue::handleMessage(const Message& message) { switch(message.what) { case MSG_FINISH_INPUT: JNIEnv* env = AndroidRuntime::getJNIEnv(); - ScopedLocalRef inputQueueObj(env, jniGetReferent(env, mInputQueueWeakGlobal)); + ScopedLocalRef inputQueueObj(env, GetReferent(env, mInputQueueWeakGlobal)); if (!inputQueueObj.get()) { ALOGW("InputQueue was finalized without being disposed"); return; diff --git a/core/jni/core_jni_helpers.cpp b/core/jni/core_jni_helpers.cpp new file mode 100644 index 0000000000000..b65053bbe8ab9 --- /dev/null +++ b/core/jni/core_jni_helpers.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core_jni_helpers.h" + +namespace android { + +namespace { + +jmethodID gGetReferent = nullptr; + +} // namespace + +jobject GetReferent(JNIEnv* env, jobject ref) { + if (gGetReferent == nullptr) { + jclass clazz = FindClassOrDie(env, "java/lang/ref/Reference"); + gGetReferent = GetMethodIDOrDie(env, clazz, "get", "()Ljava/lang/Object;"); + } + return env->CallObjectMethod(ref, gGetReferent); +} + +} // namespace android \ No newline at end of file diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h index 526804998896a..b85a42529fb6b 100644 --- a/core/jni/core_jni_helpers.h +++ b/core/jni/core_jni_helpers.h @@ -90,11 +90,10 @@ static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className, return res; } -static inline jobject jniGetReferent(JNIEnv* env, jobject ref) { - jclass cls = FindClassOrDie(env, "java/lang/ref/Reference"); - jmethodID get = GetMethodIDOrDie(env, cls, "get", "()Ljava/lang/Object;"); - return env->CallObjectMethod(ref, get); -} +/** + * Returns the result of invoking java.lang.ref.Reference.get() on a Reference object. + */ +jobject GetReferent(JNIEnv* env, jobject ref); /** * Read the specified field from jobject, and convert to std::string.