am 60ce25b3: Merge "Warn only if we\'re tearing down "live" DeathRecipient content"

* commit '60ce25b34dd3f7c1dadade9ec8769f17b12c39a6':
  Warn only if we're tearing down "live" DeathRecipient content
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index b8f2d6f..6b5ca50 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -39,6 +39,8 @@
 #include <binder/IServiceManager.h>
 #include <utils/threads.h>
 
+#include <ScopedUtfChars.h>
+
 #include <android_runtime/AndroidRuntime.h>
 
 //#undef LOGV
@@ -444,6 +446,25 @@
         return result;
     }
 
+    void warnIfStillLive() {
+        JNIEnv* env = javavm_to_jnienv(mVM);
+        if (mObject != NULL) {
+            // Okay, something is wrong -- we have a hard reference to a live death
+            // recipient on the VM side, but the list is being torn down.
+            jclass clazz = env->GetObjectClass(mObject);
+            jmethodID getnameMethod = env->GetMethodID(clazz, "getName", NULL);
+            jstring nameString = (jstring) env->CallObjectMethod(clazz, getnameMethod);
+            if (nameString) {
+                ScopedUtfChars nameUtf(env, nameString);
+                LOGW("BinderProxy is being destroyed but the application did not call "
+                        "unlinkToDeath to unlink all of its death recipients beforehand.  "
+                        "Releasing leaked death recipient: %s", nameUtf.c_str());
+                env->DeleteLocalRef(nameString);
+            }
+            env->DeleteLocalRef(clazz);
+        }
+    }
+
 protected:
     virtual ~JavaDeathRecipient()
     {
@@ -478,7 +499,10 @@
     // to the list are holding references on the list object.  Only when they are torn
     // down can the list header be destroyed.
     if (mList.size() > 0) {
-        LOGE("Retiring DRL %p with extant death recipients\n", this);
+        List< sp<JavaDeathRecipient> >::iterator iter;
+        for (iter = mList.begin(); iter != mList.end(); iter++) {
+            (*iter)->warnIfStillLive();
+        }
     }
 }