Merge "Convert Binder & BinderProxy to NativeAllocationRegistry"
am: bd6d3c5743
Change-Id: Iae1e438cc9595efe1dd68c579d42ae129ac53e5e
This commit is contained in:
@@ -27,6 +27,7 @@ import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
|
||||
import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
import libcore.util.NativeAllocationRegistry;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -90,6 +91,20 @@ public class Binder implements IBinder {
|
||||
*/
|
||||
private static volatile TransactionTracker sTransactionTracker = null;
|
||||
|
||||
/**
|
||||
* Guestimate of native memory associated with a Binder.
|
||||
*/
|
||||
private static final int NATIVE_ALLOCATION_SIZE = 500;
|
||||
|
||||
private static native long getNativeFinalizer();
|
||||
|
||||
// Use a Holder to allow static initialization of Binder in the boot image, and
|
||||
// possibly to avoid some initialization ordering issues.
|
||||
private static class NoImagePreloadHolder {
|
||||
public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
|
||||
Binder.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
|
||||
}
|
||||
|
||||
// Transaction tracking code.
|
||||
|
||||
/**
|
||||
@@ -188,8 +203,11 @@ public class Binder implements IBinder {
|
||||
}
|
||||
}
|
||||
|
||||
/* mObject is used by native code, do not remove or rename */
|
||||
private long mObject;
|
||||
/**
|
||||
* Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
|
||||
*/
|
||||
private final long mObject;
|
||||
|
||||
private IInterface mOwner;
|
||||
private String mDescriptor;
|
||||
|
||||
@@ -360,7 +378,8 @@ public class Binder implements IBinder {
|
||||
* Default constructor initializes the object.
|
||||
*/
|
||||
public Binder() {
|
||||
init();
|
||||
mObject = getNativeBBinderHolder();
|
||||
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
|
||||
|
||||
if (FIND_POTENTIAL_LEAKS) {
|
||||
final Class<? extends Binder> klass = getClass();
|
||||
@@ -638,14 +657,6 @@ public class Binder implements IBinder {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
destroyBinder();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
|
||||
if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
|
||||
// Trying to send > 800k, this is way too much
|
||||
@@ -669,8 +680,8 @@ public class Binder implements IBinder {
|
||||
}
|
||||
}
|
||||
|
||||
private native final void init();
|
||||
private native final void destroyBinder();
|
||||
private static native long getNativeBBinderHolder();
|
||||
private static native long getFinalizer();
|
||||
|
||||
// Entry point from android_util_Binder.cpp's onTransact
|
||||
private boolean execTransact(int code, long dataObj, long replyObj,
|
||||
@@ -738,11 +749,25 @@ public class Binder implements IBinder {
|
||||
*/
|
||||
final class BinderProxy implements IBinder {
|
||||
// See android_util_Binder.cpp for the native half of this.
|
||||
// TODO: Consider using NativeAllocationRegistry instead of finalization.
|
||||
|
||||
// Assume the process-wide default value when created
|
||||
volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking;
|
||||
|
||||
/**
|
||||
* Guestimate of native memory associated with a BinderProxy.
|
||||
* This includes the underlying IBinder, associated DeathRecipientList, and KeyedVector
|
||||
* that points back to us. We guess high since it includes a GlobalRef, which
|
||||
* may be in short supply.
|
||||
*/
|
||||
private static final int NATIVE_ALLOCATION_SIZE = 1000;
|
||||
|
||||
// Use a Holder to allow static initialization of BinderProxy in the boot image, and
|
||||
// to avoid some initialization ordering issues.
|
||||
private static class NoImagePreloadHolder {
|
||||
public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
|
||||
BinderProxy.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
|
||||
}
|
||||
|
||||
public native boolean pingBinder();
|
||||
public native boolean isBinderAlive();
|
||||
|
||||
@@ -778,6 +803,7 @@ final class BinderProxy implements IBinder {
|
||||
}
|
||||
}
|
||||
|
||||
private static native long getNativeFinalizer();
|
||||
public native String getInterfaceDescriptor() throws RemoteException;
|
||||
public native boolean transactNative(int code, Parcel data, Parcel reply,
|
||||
int flags) throws RemoteException;
|
||||
@@ -832,21 +858,12 @@ final class BinderProxy implements IBinder {
|
||||
}
|
||||
}
|
||||
|
||||
BinderProxy() {
|
||||
BinderProxy(long nativeData) {
|
||||
mNativeData = nativeData;
|
||||
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeData);
|
||||
mSelf = new WeakReference(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
destroy();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
private native final void destroy();
|
||||
|
||||
private static final void sendDeathNotice(DeathRecipient recipient) {
|
||||
if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
|
||||
try {
|
||||
@@ -866,11 +883,9 @@ final class BinderProxy implements IBinder {
|
||||
// TODO: Consider making the extra native-to-java call to compute this on the fly.
|
||||
final private WeakReference mSelf;
|
||||
|
||||
// Native pointer to the wrapped native IBinder object. Counted as strong reference.
|
||||
private long mObject;
|
||||
|
||||
// Native pointer to native DeathRecipientList. Counted as strong reference.
|
||||
// Basically owned by the JavaProxy object. Reference counted only because DeathRecipients
|
||||
// hold a weak reference that can be temporarily promoted.
|
||||
private long mOrgue;
|
||||
/**
|
||||
* C++ pointer to BinderProxyNativeData. That consists of strong pointers to the
|
||||
* native IBinder object, and a DeathRecipientList.
|
||||
*/
|
||||
private final long mNativeData;
|
||||
}
|
||||
|
||||
@@ -100,9 +100,8 @@ static struct binderproxy_offsets_t
|
||||
jmethodID mSendDeathNotice;
|
||||
|
||||
// Object state.
|
||||
jfieldID mObject;
|
||||
jfieldID mSelf;
|
||||
jfieldID mOrgue;
|
||||
jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
|
||||
jfieldID mSelf; // Field holds Java pointer to WeakReference to BinderProxy.
|
||||
|
||||
} gBinderProxyOffsets;
|
||||
|
||||
@@ -356,7 +355,7 @@ private:
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class JavaBBinderHolder : public RefBase
|
||||
class JavaBBinderHolder
|
||||
{
|
||||
public:
|
||||
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
|
||||
@@ -514,7 +513,7 @@ protected:
|
||||
private:
|
||||
JavaVM* const mVM;
|
||||
jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
|
||||
jweak mObjectWeak; // weak ref to the same Java-side DeathRecipient after binderDied().
|
||||
jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied().
|
||||
wp<DeathRecipientList> mList;
|
||||
};
|
||||
|
||||
@@ -586,6 +585,25 @@ static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
|
||||
env->DeleteGlobalRef((jobject)obj);
|
||||
}
|
||||
|
||||
// We aggregate native pointer fields for BinderProxy in a single object to allow
|
||||
// management with a single NativeAllocationRegistry, and to reduce the number of JNI
|
||||
// Java field accesses. This costs us some extra indirections here.
|
||||
struct BinderProxyNativeData {
|
||||
// The native IBinder proxied by this BinderProxy.
|
||||
const sp<IBinder> mObject;
|
||||
|
||||
// Death recipients for mObject. Reference counted only because DeathRecipients
|
||||
// hold a weak reference that can be temporarily promoted.
|
||||
const sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
|
||||
|
||||
BinderProxyNativeData(const sp<IBinder> &obj, DeathRecipientList *drl)
|
||||
: mObject(obj), mOrgue(drl) {};
|
||||
};
|
||||
|
||||
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
|
||||
return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
|
||||
}
|
||||
|
||||
static Mutex gProxyLock;
|
||||
|
||||
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
|
||||
@@ -617,25 +635,22 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
|
||||
env->DeleteGlobalRef(object);
|
||||
}
|
||||
|
||||
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
|
||||
DeathRecipientList* drl = new DeathRecipientList;
|
||||
BinderProxyNativeData* nativeData = new BinderProxyNativeData(val, drl);
|
||||
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor,
|
||||
(jlong)nativeData);
|
||||
if (object != NULL) {
|
||||
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
|
||||
// The proxy holds a reference to the native object.
|
||||
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
|
||||
val->incStrong((void*)javaObjectForIBinder);
|
||||
|
||||
// The native object needs to hold a weak reference back to the
|
||||
// proxy, so we can retrieve the same proxy if it is still active.
|
||||
// A JNI WeakGlobalRef would not currently work here, since it may be cleared
|
||||
// after the Java object has been condemned, and can thus yield a stale reference.
|
||||
jobject refObject = env->NewGlobalRef(
|
||||
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
|
||||
val->attachObject(&gBinderProxyOffsets, refObject,
|
||||
jnienv_to_javavm(env), proxy_cleanup);
|
||||
|
||||
// Also remember the death recipients registered on this proxy
|
||||
sp<DeathRecipientList> drl = new DeathRecipientList;
|
||||
drl->incStrong((void*)javaObjectForIBinder);
|
||||
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
|
||||
|
||||
// Note that a new object reference has been created.
|
||||
android_atomic_inc(&gNumProxyRefs);
|
||||
incRefsCreated(env);
|
||||
@@ -651,12 +666,11 @@ sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
|
||||
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
|
||||
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
|
||||
env->GetLongField(obj, gBinderOffsets.mObject);
|
||||
return jbh != NULL ? jbh->get(env, obj) : NULL;
|
||||
return jbh->get(env, obj);
|
||||
}
|
||||
|
||||
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
|
||||
return (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
return getBPNativeData(env, obj)->mObject;
|
||||
}
|
||||
|
||||
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
|
||||
@@ -849,35 +863,21 @@ static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
|
||||
IPCThreadState::self()->flushCommands();
|
||||
}
|
||||
|
||||
static void android_os_Binder_init(JNIEnv* env, jobject obj)
|
||||
static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
|
||||
{
|
||||
JavaBBinderHolder* jbh = new JavaBBinderHolder();
|
||||
if (jbh == NULL) {
|
||||
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
|
||||
return;
|
||||
}
|
||||
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
|
||||
jbh->incStrong((void*)android_os_Binder_init);
|
||||
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
|
||||
return (jlong) jbh;
|
||||
}
|
||||
|
||||
static void android_os_Binder_destroyBinder(JNIEnv* env, jobject obj)
|
||||
static void Binder_destroy(void* rawJbh)
|
||||
{
|
||||
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
|
||||
env->GetLongField(obj, gBinderOffsets.mObject);
|
||||
if (jbh != NULL) {
|
||||
env->SetLongField(obj, gBinderOffsets.mObject, 0);
|
||||
ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
|
||||
jbh->decStrong((void*)android_os_Binder_init);
|
||||
} else {
|
||||
// Encountering an uninitialized binder is harmless. All it means is that
|
||||
// the Binder was only partially initialized when its finalizer ran and called
|
||||
// destroyBinder(). The Binder could be partially initialized for several reasons.
|
||||
// For example, a Binder subclass constructor might have thrown an exception before
|
||||
// it could delegate to its superclass's constructor. Consequently init() would
|
||||
// not have been called and the holder pointer would remain NULL.
|
||||
ALOGV("Java Binder %p: ignoring uninitialized binder", obj);
|
||||
}
|
||||
JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
|
||||
ALOGV("Java Binder: deleting holder %p", jbh);
|
||||
delete jbh;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
|
||||
return (jlong) Binder_destroy;
|
||||
}
|
||||
|
||||
static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
|
||||
@@ -896,8 +896,8 @@ static const JNINativeMethod gBinderMethods[] = {
|
||||
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
|
||||
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
|
||||
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
|
||||
{ "init", "()V", (void*)android_os_Binder_init },
|
||||
{ "destroyBinder", "()V", (void*)android_os_Binder_destroyBinder },
|
||||
{ "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
|
||||
{ "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
|
||||
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
|
||||
};
|
||||
|
||||
@@ -1004,8 +1004,7 @@ static int int_register_android_os_BinderInternal(JNIEnv* env)
|
||||
|
||||
static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
|
||||
{
|
||||
IBinder* target = (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
IBinder* target = getBPNativeData(env, obj)->mObject.get();
|
||||
if (target == NULL) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
@@ -1015,7 +1014,7 @@ static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
|
||||
|
||||
static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
|
||||
{
|
||||
IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
IBinder* target = getBPNativeData(env, obj)->mObject.get();
|
||||
if (target != NULL) {
|
||||
const String16& desc = target->getInterfaceDescriptor();
|
||||
return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
|
||||
@@ -1028,8 +1027,7 @@ static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobjec
|
||||
|
||||
static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
|
||||
{
|
||||
IBinder* target = (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
IBinder* target = getBPNativeData(env, obj)->mObject.get();
|
||||
if (target == NULL) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
@@ -1151,8 +1149,7 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
IBinder* target = (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
IBinder* target = getBPNativeData(env, obj)->mObject.get();
|
||||
if (target == NULL) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
|
||||
return JNI_FALSE;
|
||||
@@ -1202,8 +1199,8 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
|
||||
return;
|
||||
}
|
||||
|
||||
IBinder* target = (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
BinderProxyNativeData *nd = getBPNativeData(env, obj);
|
||||
IBinder* target = nd->mObject.get();
|
||||
if (target == NULL) {
|
||||
ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
|
||||
assert(false);
|
||||
@@ -1212,8 +1209,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
|
||||
LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
|
||||
|
||||
if (!target->localBinder()) {
|
||||
DeathRecipientList* list = (DeathRecipientList*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
|
||||
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) {
|
||||
@@ -1234,8 +1230,8 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
|
||||
return res;
|
||||
}
|
||||
|
||||
IBinder* target = (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
BinderProxyNativeData* nd = getBPNativeData(env, obj);
|
||||
IBinder* target = nd->mObject.get();
|
||||
if (target == NULL) {
|
||||
ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
|
||||
return JNI_FALSE;
|
||||
@@ -1247,8 +1243,7 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
|
||||
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);
|
||||
DeathRecipientList* list = nd->mOrgue.get();
|
||||
sp<JavaDeathRecipient> origJDR = list->find(recipient);
|
||||
LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
|
||||
if (origJDR != NULL) {
|
||||
@@ -1274,27 +1269,22 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
|
||||
return res;
|
||||
}
|
||||
|
||||
static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
|
||||
static void BinderProxy_destroy(void* rawNativeData)
|
||||
{
|
||||
// Don't race with construction/initialization
|
||||
AutoMutex _l(gProxyLock);
|
||||
|
||||
IBinder* b = (IBinder*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mObject);
|
||||
DeathRecipientList* drl = (DeathRecipientList*)
|
||||
env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
|
||||
|
||||
LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
|
||||
if (b != nullptr) {
|
||||
env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
|
||||
env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
|
||||
drl->decStrong((void*)javaObjectForIBinder);
|
||||
b->decStrong((void*)javaObjectForIBinder);
|
||||
}
|
||||
|
||||
BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
|
||||
LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
|
||||
nativeData->mObject.get(), nativeData->mOrgue.get());
|
||||
delete (BinderProxyNativeData *) rawNativeData;
|
||||
IPCThreadState::self()->flushCommands();
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
|
||||
return (jlong) BinderProxy_destroy;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const JNINativeMethod gBinderProxyMethods[] = {
|
||||
@@ -1305,7 +1295,7 @@ static const JNINativeMethod gBinderProxyMethods[] = {
|
||||
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
|
||||
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
|
||||
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
|
||||
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
|
||||
{"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
|
||||
};
|
||||
|
||||
const char* const kBinderProxyPathName = "android/os/BinderProxy";
|
||||
@@ -1317,14 +1307,13 @@ static int int_register_android_os_BinderProxy(JNIEnv* env)
|
||||
|
||||
clazz = FindClassOrDie(env, kBinderProxyPathName);
|
||||
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
|
||||
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
|
||||
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "(J)V");
|
||||
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
|
||||
"(Landroid/os/IBinder$DeathRecipient;)V");
|
||||
|
||||
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
|
||||
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
|
||||
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
|
||||
"Ljava/lang/ref/WeakReference;");
|
||||
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
|
||||
|
||||
clazz = FindClassOrDie(env, "java/lang/Class");
|
||||
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
|
||||
|
||||
Reference in New Issue
Block a user