summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arpit Singh <arpitks@google.com> 2024-02-21 17:25:23 +0000
committer Arpit Singh <arpitks@google.com> 2024-02-21 18:35:53 +0000
commit43c34c8991e5d2a11296d9449b3348189df8f616 (patch)
tree7205c707a011af8c658f8a0f5f22f2d6d4fc7021
parent3d8cc938500d687fa071cbd91d245fe10daba59f (diff)
Use ScopedLocalRef in InputEvent jni function
This CL updates some jni functions that manipulate Key and Motion events to use ScopedLocalRef instead of plain jobject for better life-cycle tracking. Test: presubmit Bug: 324375527 Change-Id: I154b0606d3c0912f0df7a890faf7246b575863f5
-rw-r--r--core/jni/android_view_InputEventReceiver.cpp9
-rw-r--r--core/jni/android_view_KeyCharacterMap.cpp8
-rw-r--r--core/jni/android_view_KeyEvent.cpp22
-rw-r--r--core/jni/android_view_KeyEvent.h7
-rw-r--r--core/jni/android_view_MotionEvent.cpp23
-rw-r--r--core/jni/android_view_MotionEvent.h11
-rw-r--r--core/jni/android_view_MotionPredictor.cpp3
-rw-r--r--native/android/input.cpp6
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp17
9 files changed, 59 insertions, 47 deletions
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index a88314434340..f1b93db3e731 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -371,7 +371,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
}
}
- jobject inputEventObj;
+ ScopedLocalRef<jobject> inputEventObj(env);
switch (inputEvent->getType()) {
case InputEventType::KEY:
if (kDebugDispatchCycle) {
@@ -447,20 +447,19 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
default:
assert(false); // InputConsumer should prevent this from ever happening
- inputEventObj = nullptr;
}
- if (inputEventObj) {
+ if (inputEventObj.get()) {
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName().c_str());
}
env->CallVoidMethod(receiverObj.get(),
- gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
+ gInputEventReceiverClassInfo.dispatchInputEvent, seq,
+ inputEventObj.get());
if (env->ExceptionCheck()) {
ALOGE("Exception dispatching input event.");
skipCallbacks = true;
}
- env->DeleteLocalRef(inputEventObj);
} else {
ALOGW("channel '%s' ~ Failed to obtain event object.",
getInputChannelName().c_str());
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index 3325e893980d..2b19ddfed5eb 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -219,10 +219,10 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr,
result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
if (result) {
for (size_t i = 0; i < events.size(); i++) {
- jobject keyEventObj = android_view_KeyEvent_obtainAsCopy(env, events.itemAt(i));
- if (!keyEventObj) break; // threw OOM exception
- env->SetObjectArrayElement(result, jsize(i), keyEventObj);
- env->DeleteLocalRef(keyEventObj);
+ ScopedLocalRef<jobject> keyEventObj =
+ android_view_KeyEvent_obtainAsCopy(env, events.itemAt(i));
+ if (!keyEventObj.get()) break; // threw OOM exception
+ env->SetObjectArrayElement(result, jsize(i), keyEventObj.get());
}
}
}
diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp
index 908ab5ed2eac..ca8752f93e11 100644
--- a/core/jni/android_view_KeyEvent.cpp
+++ b/core/jni/android_view_KeyEvent.cpp
@@ -94,21 +94,23 @@ static struct {
// ----------------------------------------------------------------------------
-jobject android_view_KeyEvent_obtainAsCopy(JNIEnv* env, const KeyEvent& event) {
+ScopedLocalRef<jobject> android_view_KeyEvent_obtainAsCopy(JNIEnv* env, const KeyEvent& event) {
ScopedLocalRef<jbyteArray> hmac = toJbyteArray(env, event.getHmac());
- jobject eventObj =
- env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, gKeyEventClassInfo.obtain,
- event.getId(), event.getDownTime(), event.getEventTime(),
- event.getAction(), event.getKeyCode(),
- event.getRepeatCount(), event.getMetaState(),
- event.getDeviceId(), event.getScanCode(), event.getFlags(),
- event.getSource(), event.getDisplayId(), hmac.get(),
- nullptr);
+ ScopedLocalRef<jobject>
+ eventObj(env,
+ env->CallStaticObjectMethod(gKeyEventClassInfo.clazz,
+ gKeyEventClassInfo.obtain, event.getId(),
+ event.getDownTime(), event.getEventTime(),
+ event.getAction(), event.getKeyCode(),
+ event.getRepeatCount(), event.getMetaState(),
+ event.getDeviceId(), event.getScanCode(),
+ event.getFlags(), event.getSource(),
+ event.getDisplayId(), hmac.get(), nullptr));
if (env->ExceptionCheck()) {
ALOGE("An exception occurred while obtaining a key event.");
LOGE_EX(env);
env->ExceptionClear();
- return NULL;
+ return ScopedLocalRef<jobject>(env);
}
return eventObj;
}
diff --git a/core/jni/android_view_KeyEvent.h b/core/jni/android_view_KeyEvent.h
index eab7c972817b..838f0130bd40 100644
--- a/core/jni/android_view_KeyEvent.h
+++ b/core/jni/android_view_KeyEvent.h
@@ -17,17 +17,20 @@
#ifndef _ANDROID_VIEW_KEYEVENT_H
#define _ANDROID_VIEW_KEYEVENT_H
-#include "jni.h"
+#include <nativehelper/scoped_local_ref.h>
#include <utils/Errors.h>
#include <utils/threads.h>
+#include "jni.h"
+
namespace android {
class KeyEvent;
/* Obtains an instance of a DVM KeyEvent object as a copy of a native KeyEvent instance.
* Returns NULL on error. */
-extern jobject android_view_KeyEvent_obtainAsCopy(JNIEnv* env, const KeyEvent& event);
+extern ScopedLocalRef<jobject> android_view_KeyEvent_obtainAsCopy(JNIEnv* env,
+ const KeyEvent& event);
/* Copies the contents of a DVM KeyEvent object to a native KeyEvent instance.
* Returns non-zero on error. */
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 33fbdb83cf48..285dee364bb0 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -77,25 +77,28 @@ MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj
env->GetLongField(eventObj, gMotionEventClassInfo.mNativePtr));
}
-static void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
- MotionEvent* event) {
- env->SetLongField(eventObj, gMotionEventClassInfo.mNativePtr,
- reinterpret_cast<jlong>(event));
+static void android_view_MotionEvent_setNativePtr(JNIEnv* env, ScopedLocalRef<jobject>& eventObj,
+ MotionEvent* event) {
+ env->SetLongField(eventObj.get(), gMotionEventClassInfo.mNativePtr,
+ reinterpret_cast<jlong>(event));
}
-jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent& event) {
+ScopedLocalRef<jobject> android_view_MotionEvent_obtainAsCopy(JNIEnv* env,
+ const MotionEvent& event) {
std::unique_ptr<MotionEvent> destEvent = std::make_unique<MotionEvent>();
destEvent->copyFrom(&event, true);
return android_view_MotionEvent_obtainFromNative(env, std::move(destEvent));
}
-jobject android_view_MotionEvent_obtainFromNative(JNIEnv* env, std::unique_ptr<MotionEvent> event) {
+ScopedLocalRef<jobject> android_view_MotionEvent_obtainFromNative(
+ JNIEnv* env, std::unique_ptr<MotionEvent> event) {
if (event == nullptr) {
- return nullptr;
+ return ScopedLocalRef<jobject>(env);
}
- jobject eventObj =
- env->CallStaticObjectMethod(gMotionEventClassInfo.clazz, gMotionEventClassInfo.obtain);
- if (env->ExceptionCheck() || !eventObj) {
+ ScopedLocalRef<jobject> eventObj(env,
+ env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
+ gMotionEventClassInfo.obtain));
+ if (env->ExceptionCheck() || !eventObj.get()) {
LOGE_EX(env);
LOG_ALWAYS_FATAL("An exception occurred while obtaining a Java motion event.");
}
diff --git a/core/jni/android_view_MotionEvent.h b/core/jni/android_view_MotionEvent.h
index e81213608d68..b1bf1c435e26 100644
--- a/core/jni/android_view_MotionEvent.h
+++ b/core/jni/android_view_MotionEvent.h
@@ -17,21 +17,24 @@
#ifndef _ANDROID_VIEW_MOTIONEVENT_H
#define _ANDROID_VIEW_MOTIONEVENT_H
-#include "jni.h"
+#include <nativehelper/scoped_local_ref.h>
#include <utils/Errors.h>
+#include "jni.h"
+
namespace android {
class MotionEvent;
/* Obtains an instance of a DVM MotionEvent object as a copy of a native MotionEvent instance.
* Returns NULL on error. */
-extern jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent& event);
+extern ScopedLocalRef<jobject> android_view_MotionEvent_obtainAsCopy(JNIEnv* env,
+ const MotionEvent& event);
/* Obtains an instance of a Java MotionEvent object, taking over the ownership of the provided
* native MotionEvent instance. Crashes on error. */
-extern jobject android_view_MotionEvent_obtainFromNative(JNIEnv* env,
- std::unique_ptr<MotionEvent> event);
+extern ScopedLocalRef<jobject> android_view_MotionEvent_obtainFromNative(
+ JNIEnv* env, std::unique_ptr<MotionEvent> event);
/* Gets the underlying native MotionEvent instance within a DVM MotionEvent object.
* Returns NULL if the event is NULL or if it is uninitialized. */
diff --git a/core/jni/android_view_MotionPredictor.cpp b/core/jni/android_view_MotionPredictor.cpp
index de3e81c7088b..0707e99205aa 100644
--- a/core/jni/android_view_MotionPredictor.cpp
+++ b/core/jni/android_view_MotionPredictor.cpp
@@ -61,7 +61,8 @@ static jobject android_view_MotionPredictor_nativePredict(JNIEnv* env, jclass cl
MotionPredictor* predictor = reinterpret_cast<MotionPredictor*>(ptr);
return android_view_MotionEvent_obtainFromNative(env,
predictor->predict(static_cast<nsecs_t>(
- predictionTimeNanos)));
+ predictionTimeNanos)))
+ .release();
}
static jboolean android_view_MotionPredictor_nativeIsPredictionAvailable(JNIEnv* env, jclass clazz,
diff --git a/native/android/input.cpp b/native/android/input.cpp
index 4708e69447ec..53699bc706ea 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -321,11 +321,13 @@ jobject AInputEvent_toJava(JNIEnv* env, const AInputEvent* aInputEvent) {
case AINPUT_EVENT_TYPE_MOTION:
return android::android_view_MotionEvent_obtainAsCopy(env,
static_cast<const MotionEvent&>(
- *aInputEvent));
+ *aInputEvent))
+ .release();
case AINPUT_EVENT_TYPE_KEY:
return android::android_view_KeyEvent_obtainAsCopy(env,
static_cast<const KeyEvent&>(
- *aInputEvent));
+ *aInputEvent))
+ .release();
default:
LOG_ALWAYS_FATAL("Unexpected event type %d in AInputEvent_toJava.", eventType);
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 93c0c6258e9b..2150eb33234f 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1509,15 +1509,14 @@ bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t
ScopedLocalRef<jobject> inputEventObj(env);
switch (inputEvent.getType()) {
case InputEventType::KEY:
- inputEventObj.reset(
+ inputEventObj =
android_view_KeyEvent_obtainAsCopy(env,
- static_cast<const KeyEvent&>(inputEvent)));
+ static_cast<const KeyEvent&>(inputEvent));
break;
case InputEventType::MOTION:
- inputEventObj.reset(
- android_view_MotionEvent_obtainAsCopy(env,
- static_cast<const MotionEvent&>(
- inputEvent)));
+ inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
+ static_cast<const MotionEvent&>(
+ inputEvent));
break;
default:
return true; // dispatch the event normally
@@ -1559,7 +1558,7 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent& keyEvent,
const nsecs_t when = keyEvent.getEventTime();
JNIEnv* env = jniEnv();
- ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_obtainAsCopy(env, keyEvent));
+ ScopedLocalRef<jobject> keyEventObj = android_view_KeyEvent_obtainAsCopy(env, keyEvent);
if (!keyEventObj.get()) {
ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
return;
@@ -1639,7 +1638,7 @@ nsecs_t NativeInputManager::interceptKeyBeforeDispatching(const sp<IBinder>& tok
// Token may be null
ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
- ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_obtainAsCopy(env, keyEvent));
+ ScopedLocalRef<jobject> keyEventObj = android_view_KeyEvent_obtainAsCopy(env, keyEvent);
if (!keyEventObj.get()) {
ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
return 0;
@@ -1670,7 +1669,7 @@ std::optional<KeyEvent> NativeInputManager::dispatchUnhandledKey(const sp<IBinde
// Note: tokenObj may be null.
ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
- ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_obtainAsCopy(env, keyEvent));
+ ScopedLocalRef<jobject> keyEventObj = android_view_KeyEvent_obtainAsCopy(env, keyEvent);
if (!keyEventObj.get()) {
ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
return {};