Clean up JNI methods of InputDispatcherPolicy
Some cleanup, including using ScopedLocalRef for all java objects, and
flattening nested conditionals for readability.
Bug: 279927189
Bug: 245989146
Test: Presubmit
Change-Id: Ib77b8f3d94ff2fa39573a835707500eb27d62306
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index f350eb2..7ff3ecb 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1297,37 +1297,38 @@
bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) {
ATRACE_CALL();
- jobject inputEventObj;
-
JNIEnv* env = jniEnv();
+
+ ScopedLocalRef<jobject> inputEventObj(env);
switch (inputEvent.getType()) {
case InputEventType::KEY:
- inputEventObj =
+ inputEventObj.reset(
android_view_KeyEvent_fromNative(env,
- static_cast<const KeyEvent*>(&inputEvent));
+ static_cast<const KeyEvent*>(&inputEvent)));
break;
case InputEventType::MOTION:
- inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
- static_cast<const MotionEvent&>(
- inputEvent));
+ inputEventObj.reset(
+ android_view_MotionEvent_obtainAsCopy(env,
+ static_cast<const MotionEvent&>(
+ inputEvent)));
break;
default:
return true; // dispatch the event normally
}
- if (!inputEventObj) {
+ if (!inputEventObj.get()) {
ALOGE("Failed to obtain input event object for filterInputEvent.");
return true; // dispatch the event normally
}
// The callee is responsible for recycling the event.
- jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
- inputEventObj, policyFlags);
+ const jboolean continueEventDispatch =
+ env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
+ inputEventObj.get(), policyFlags);
if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
- pass = true;
+ return true; // dispatch the event normally
}
- env->DeleteLocalRef(inputEventObj);
- return pass;
+ return continueEventDispatch;
}
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent& keyEvent,
@@ -1337,35 +1338,33 @@
// - Ignore untrusted events and pass them along.
// - Ask the window manager what to do with normal events and trusted injected events.
// - For normal events wake and brighten the screen if currently off or dim.
- bool interactive = mInteractive.load();
+ const bool interactive = mInteractive.load();
if (interactive) {
policyFlags |= POLICY_FLAG_INTERACTIVE;
}
- if ((policyFlags & POLICY_FLAG_TRUSTED)) {
- nsecs_t when = keyEvent.getEventTime();
- JNIEnv* env = jniEnv();
- jobject keyEventObj = android_view_KeyEvent_fromNative(env, &keyEvent);
- jint wmActions;
- if (keyEventObj) {
- wmActions = env->CallIntMethod(mServiceObj,
- gServiceClassInfo.interceptKeyBeforeQueueing,
- keyEventObj, policyFlags);
- if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
- wmActions = 0;
- }
- android_view_KeyEvent_recycle(env, keyEventObj);
- env->DeleteLocalRef(keyEventObj);
- } else {
- ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
- wmActions = 0;
- }
- handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
- } else {
+ if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
if (interactive) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
+ return;
}
+
+ const nsecs_t when = keyEvent.getEventTime();
+ JNIEnv* env = jniEnv();
+ ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, &keyEvent));
+ if (!keyEventObj.get()) {
+ ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
+ return;
+ }
+
+ jint wmActions = env->CallIntMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeQueueing,
+ keyEventObj.get(), policyFlags);
+ if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
+ wmActions = 0;
+ }
+ android_view_KeyEvent_recycle(env, keyEventObj.get());
+ handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
}
void NativeInputManager::interceptMotionBeforeQueueing(int32_t displayId, nsecs_t when,
@@ -1376,30 +1375,32 @@
// - No special filtering for injected events required at this time.
// - Filter normal events based on screen state.
// - For normal events brighten (but do not wake) the screen if currently dim.
- bool interactive = mInteractive.load();
+ const bool interactive = mInteractive.load();
if (interactive) {
policyFlags |= POLICY_FLAG_INTERACTIVE;
}
- if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
- if (policyFlags & POLICY_FLAG_INTERACTIVE) {
- policyFlags |= POLICY_FLAG_PASS_TO_USER;
- } else {
- JNIEnv* env = jniEnv();
- jint wmActions = env->CallIntMethod(mServiceObj,
- gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
- displayId, when, policyFlags);
- if (checkAndClearExceptionFromCallback(env,
- "interceptMotionBeforeQueueingNonInteractive")) {
- wmActions = 0;
- }
- handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
- }
- } else {
+ if ((policyFlags & POLICY_FLAG_TRUSTED) == 0 || (policyFlags & POLICY_FLAG_INJECTED)) {
if (interactive) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
+ return;
}
+
+ if (policyFlags & POLICY_FLAG_INTERACTIVE) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
+ return;
+ }
+
+ JNIEnv* env = jniEnv();
+ const jint wmActions =
+ env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
+ displayId, when, policyFlags);
+ if (checkAndClearExceptionFromCallback(env, "interceptMotionBeforeQueueingNonInteractive")) {
+ return;
+ }
+ handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
}
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
@@ -1421,34 +1422,29 @@
// - Ignore untrusted events and pass them along.
// - Filter normal events and trusted injected events through the window manager policy to
// handle the HOME key and the like.
- nsecs_t result = 0;
- if (policyFlags & POLICY_FLAG_TRUSTED) {
- JNIEnv* env = jniEnv();
- ScopedLocalFrame localFrame(env);
-
- // Token may be null
- jobject tokenObj = javaObjectForIBinder(env, token);
-
- jobject keyEventObj = android_view_KeyEvent_fromNative(env, &keyEvent);
- if (keyEventObj) {
- jlong delayMillis = env->CallLongMethod(mServiceObj,
- gServiceClassInfo.interceptKeyBeforeDispatching,
- tokenObj, keyEventObj, policyFlags);
- bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
- android_view_KeyEvent_recycle(env, keyEventObj);
- env->DeleteLocalRef(keyEventObj);
- if (!error) {
- if (delayMillis < 0) {
- result = -1;
- } else if (delayMillis > 0) {
- result = milliseconds_to_nanoseconds(delayMillis);
- }
- }
- } else {
- ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
- }
+ if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
+ return 0;
}
- return result;
+
+ JNIEnv* env = jniEnv();
+ ScopedLocalFrame localFrame(env);
+
+ // Token may be null
+ ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
+ ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, &keyEvent));
+ if (!keyEventObj.get()) {
+ ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
+ return 0;
+ }
+
+ const jlong delayMillis =
+ env->CallLongMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeDispatching,
+ tokenObj.get(), keyEventObj.get(), policyFlags);
+ android_view_KeyEvent_recycle(env, keyEventObj.get());
+ if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching")) {
+ return 0;
+ }
+ return delayMillis < 0 ? -1 : milliseconds_to_nanoseconds(delayMillis);
}
std::optional<KeyEvent> NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
@@ -1457,38 +1453,39 @@
ATRACE_CALL();
// Policy:
// - Ignore untrusted events and do not perform default handling.
- std::optional<KeyEvent> result;
- if (policyFlags & POLICY_FLAG_TRUSTED) {
- JNIEnv* env = jniEnv();
- ScopedLocalFrame localFrame(env);
-
- // Note: tokenObj may be null.
- jobject tokenObj = javaObjectForIBinder(env, token);
- jobject keyEventObj = android_view_KeyEvent_fromNative(env, &keyEvent);
- if (keyEventObj) {
- jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
- gServiceClassInfo.dispatchUnhandledKey,
- tokenObj, keyEventObj, policyFlags);
- if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
- fallbackKeyEventObj = nullptr;
- }
- android_view_KeyEvent_recycle(env, keyEventObj);
- env->DeleteLocalRef(keyEventObj);
-
- if (fallbackKeyEventObj) {
- // Note: outFallbackKeyEvent may be the same object as keyEvent.
- result = KeyEvent();
- if (android_view_KeyEvent_toNative(env, fallbackKeyEventObj, &(*result)) != OK) {
- result.reset();
- }
- android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
- env->DeleteLocalRef(fallbackKeyEventObj);
- }
- } else {
- ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
- }
+ if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
+ return {};
}
- return result;
+
+ JNIEnv* env = jniEnv();
+ ScopedLocalFrame localFrame(env);
+
+ // Note: tokenObj may be null.
+ ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
+ ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, &keyEvent));
+ if (!keyEventObj.get()) {
+ ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
+ return {};
+ }
+
+ ScopedLocalRef<jobject>
+ fallbackKeyEventObj(env,
+ env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.dispatchUnhandledKey,
+ tokenObj.get(), keyEventObj.get(),
+ policyFlags));
+
+ android_view_KeyEvent_recycle(env, keyEventObj.get());
+ if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey") ||
+ !fallbackKeyEventObj.get()) {
+ return {};
+ }
+
+ KeyEvent fallbackEvent;
+ LOG_ALWAYS_FATAL_IF(
+ android_view_KeyEvent_toNative(env, fallbackKeyEventObj.get(), &fallbackEvent) != OK);
+ android_view_KeyEvent_recycle(env, fallbackKeyEventObj.get());
+ return fallbackEvent;
}
void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) {