OSDN Git Service

Changed local refs in JNI to ScopedLocalRef
authorchaviw <chaviw@google.com>
Thu, 9 May 2019 22:22:54 +0000 (15:22 -0700)
committerchaviw <chaviw@google.com>
Thu, 9 May 2019 22:37:24 +0000 (15:37 -0700)
Objects were leaking in InputManagerService JNI since there were calls
from the native process without clearing the local reference.
Converted the references to ScopedLocalRef so they get removed
automatically when out of scope.

Test: No longer leaking IWindow when opening/closing apps
Fixes: 131355264
Change-Id: I054faeb83360d7c43c3491680c3a39ba0b0c8351

services/core/jni/com_android_server_input_InputManagerService.cpp

index 204a1ea..00671c1 100644 (file)
@@ -724,19 +724,18 @@ nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApp
 
     JNIEnv* env = jniEnv();
 
-    jobject tokenObj = javaObjectForIBinder(env, token);
-    jstring reasonObj = env->NewStringUTF(reason.c_str());
+    ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
+    ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
 
     jlong newTimeout = env->CallLongMethod(mServiceObj,
-                gServiceClassInfo.notifyANR, tokenObj,
-                reasonObj);
+                gServiceClassInfo.notifyANR, tokenObj.get(),
+                reasonObj.get());
     if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
         newTimeout = 0; // abort dispatch
     } else {
         assert(newTimeout >= 0);
     }
 
-    env->DeleteLocalRef(reasonObj);
     return newTimeout;
 }
 
@@ -748,10 +747,10 @@ void NativeInputManager::notifyInputChannelBroken(const sp<IBinder>& token) {
 
     JNIEnv* env = jniEnv();
 
-    jobject tokenObj = javaObjectForIBinder(env, token);
-    if (tokenObj) {
+    ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
+    if (tokenObj.get()) {
         env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken,
-                tokenObj);
+                tokenObj.get());
         checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
     }
 }
@@ -765,10 +764,10 @@ void NativeInputManager::notifyFocusChanged(const sp<IBinder>& oldToken,
 
     JNIEnv* env = jniEnv();
 
-    jobject oldTokenObj = javaObjectForIBinder(env, oldToken);
-    jobject newTokenObj = javaObjectForIBinder(env, newToken);
+    ScopedLocalRef<jobject> oldTokenObj(env, javaObjectForIBinder(env, oldToken));
+    ScopedLocalRef<jobject> newTokenObj(env, javaObjectForIBinder(env, newToken));
     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyFocusChanged,
-            oldTokenObj, newTokenObj);
+            oldTokenObj.get(), newTokenObj.get());
     checkAndClearExceptionFromCallback(env, "notifyFocusChanged");
 }
 
@@ -1141,13 +1140,13 @@ nsecs_t NativeInputManager::interceptKeyBeforeDispatching(
         JNIEnv* env = jniEnv();
 
         // Token may be null
-        jobject tokenObj = javaObjectForIBinder(env, token);
+        ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
 
         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
         if (keyEventObj) {
             jlong delayMillis = env->CallLongMethod(mServiceObj,
                     gServiceClassInfo.interceptKeyBeforeDispatching,
-                    tokenObj, keyEventObj, policyFlags);
+                    tokenObj.get(), keyEventObj, policyFlags);
             bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
             android_view_KeyEvent_recycle(env, keyEventObj);
             env->DeleteLocalRef(keyEventObj);
@@ -1175,12 +1174,12 @@ bool NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
         JNIEnv* env = jniEnv();
 
         // Note: tokenObj may be null.
-        jobject tokenObj = javaObjectForIBinder(env, token);
+        ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
         if (keyEventObj) {
             jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
                     gServiceClassInfo.dispatchUnhandledKey,
-                    tokenObj, keyEventObj, policyFlags);
+                    tokenObj.get(), keyEventObj, policyFlags);
             if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
                 fallbackKeyEventObj = nullptr;
             }
@@ -1225,8 +1224,9 @@ void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedTok
     ATRACE_CALL();
     JNIEnv* env = jniEnv();
 
-    jobject touchedTokenObj = javaObjectForIBinder(env, touchedToken);
-    env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus, touchedTokenObj);
+    ScopedLocalRef<jobject> touchedTokenObj(env, javaObjectForIBinder(env, touchedToken));
+    env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus,
+            touchedTokenObj.get());
     checkAndClearExceptionFromCallback(env, "onPointerDownOutsideFocus");
 }