static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, jobject recipient, jint flags) // throws RemoteException { if (recipient == NULL) { jniThrowNullPointerException(env, NULL); return; } IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); assert(false); } LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient); if (!target->localBinder()) { DeathRecipientList* list = (DeathRecipientList*) env->GetLongField(obj, gBinderProxyOffsets.mOrgue); sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); status_t err = target->linkToDeath(jdr, NULL, flags); if (err != NO_ERROR) { // Failure adding the death recipient, so clear its reference // now. jdr->clearReference(); signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); } } }
static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, jobject recipient, jint flags) // throws RemoteException { if (recipient == NULL) { jniThrowNullPointerException(env, NULL); return; } BinderProxyNativeData *nd = getBPNativeData(env, obj); IBinder* target = nd->mObject.get(); LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient); if (!target->localBinder()) { DeathRecipientList* list = nd->mOrgue.get(); sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); status_t err = target->linkToDeath(jdr, NULL, flags); if (err != NO_ERROR) { // Failure adding the death recipient, so clear its reference // now. jdr->clearReference(); signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); } } }
static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, jobject recipient, jint flags) { jboolean res = JNI_FALSE; if (recipient == NULL) { jniThrowNullPointerException(env, NULL); return res; } IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); return JNI_FALSE; } LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient); if (!target->localBinder()) { status_t err = NAME_NOT_FOUND; // If we find the matching recipient, proceed to unlink using that DeathRecipientList* list = (DeathRecipientList*) env->GetLongField(obj, gBinderProxyOffsets.mOrgue); sp<JavaDeathRecipient> origJDR = list->find(recipient); LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get()); if (origJDR != NULL) { wp<IBinder::DeathRecipient> dr; err = target->unlinkToDeath(origJDR, NULL, flags, &dr); if (err == NO_ERROR && dr != NULL) { sp<IBinder::DeathRecipient> sdr = dr.promote(); JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get()); if (jdr != NULL) { jdr->clearReference(); } } } if (err == NO_ERROR || err == DEAD_OBJECT) { res = JNI_TRUE; } else { jniThrowException(env, "java/util/NoSuchElementException", "Death link does not exist"); } } return res; }