android_util_Binder.cpp revision 177b187cc6b47690f65a1e7b9ea2545e37e76179
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "JavaBinder"
18//#define LOG_NDEBUG 0
19
20#include "android_os_Parcel.h"
21#include "android_util_Binder.h"
22
23#include "JNIHelp.h"
24
25#include <fcntl.h>
26#include <inttypes.h>
27#include <stdio.h>
28#include <sys/stat.h>
29#include <sys/types.h>
30#include <unistd.h>
31
32#include <utils/Atomic.h>
33#include <binder/IInterface.h>
34#include <binder/IPCThreadState.h>
35#include <utils/Log.h>
36#include <utils/SystemClock.h>
37#include <utils/List.h>
38#include <utils/KeyedVector.h>
39#include <log/logger.h>
40#include <binder/Parcel.h>
41#include <binder/ProcessState.h>
42#include <binder/IServiceManager.h>
43#include <utils/threads.h>
44#include <utils/String8.h>
45
46#include <ScopedUtfChars.h>
47#include <ScopedLocalRef.h>
48
49#include <android_runtime/AndroidRuntime.h>
50
51//#undef ALOGV
52//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
53
54#define DEBUG_DEATH 0
55#if DEBUG_DEATH
56#define LOGDEATH ALOGD
57#else
58#define LOGDEATH ALOGV
59#endif
60
61using namespace android;
62
63// ----------------------------------------------------------------------------
64
65static struct bindernative_offsets_t
66{
67    // Class state.
68    jclass mClass;
69    jmethodID mExecTransact;
70
71    // Object state.
72    jfieldID mObject;
73
74} gBinderOffsets;
75
76// ----------------------------------------------------------------------------
77
78static struct binderinternal_offsets_t
79{
80    // Class state.
81    jclass mClass;
82    jmethodID mForceGc;
83
84} gBinderInternalOffsets;
85
86// ----------------------------------------------------------------------------
87
88static struct debug_offsets_t
89{
90    // Class state.
91    jclass mClass;
92
93} gDebugOffsets;
94
95// ----------------------------------------------------------------------------
96
97static struct error_offsets_t
98{
99    jclass mClass;
100} gErrorOffsets;
101
102// ----------------------------------------------------------------------------
103
104static struct binderproxy_offsets_t
105{
106    // Class state.
107    jclass mClass;
108    jmethodID mConstructor;
109    jmethodID mSendDeathNotice;
110
111    // Object state.
112    jfieldID mObject;
113    jfieldID mSelf;
114    jfieldID mOrgue;
115
116} gBinderProxyOffsets;
117
118static struct class_offsets_t
119{
120    jmethodID mGetName;
121} gClassOffsets;
122
123// ----------------------------------------------------------------------------
124
125static struct log_offsets_t
126{
127    // Class state.
128    jclass mClass;
129    jmethodID mLogE;
130} gLogOffsets;
131
132static struct parcel_file_descriptor_offsets_t
133{
134    jclass mClass;
135    jmethodID mConstructor;
136} gParcelFileDescriptorOffsets;
137
138static struct strict_mode_callback_offsets_t
139{
140    jclass mClass;
141    jmethodID mCallback;
142} gStrictModeCallbackOffsets;
143
144// ****************************************************************************
145// ****************************************************************************
146// ****************************************************************************
147
148static volatile int32_t gNumRefsCreated = 0;
149static volatile int32_t gNumProxyRefs = 0;
150static volatile int32_t gNumLocalRefs = 0;
151static volatile int32_t gNumDeathRefs = 0;
152
153static void incRefsCreated(JNIEnv* env)
154{
155    int old = android_atomic_inc(&gNumRefsCreated);
156    if (old == 200) {
157        android_atomic_and(0, &gNumRefsCreated);
158        env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
159                gBinderInternalOffsets.mForceGc);
160    } else {
161        ALOGV("Now have %d binder ops", old);
162    }
163}
164
165static JavaVM* jnienv_to_javavm(JNIEnv* env)
166{
167    JavaVM* vm;
168    return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
169}
170
171static JNIEnv* javavm_to_jnienv(JavaVM* vm)
172{
173    JNIEnv* env;
174    return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
175}
176
177static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
178{
179    env->ExceptionClear();
180
181    jstring tagstr = env->NewStringUTF(LOG_TAG);
182    jstring msgstr = NULL;
183    if (tagstr != NULL) {
184        msgstr = env->NewStringUTF(msg);
185    }
186
187    if ((tagstr == NULL) || (msgstr == NULL)) {
188        env->ExceptionClear();      /* assume exception (OOM?) was thrown */
189        ALOGE("Unable to call Log.e()\n");
190        ALOGE("%s", msg);
191        goto bail;
192    }
193
194    env->CallStaticIntMethod(
195        gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
196    if (env->ExceptionCheck()) {
197        /* attempting to log the failure has failed */
198        ALOGW("Failed trying to log exception, msg='%s'\n", msg);
199        env->ExceptionClear();
200    }
201
202    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
203        /*
204         * It's an Error: Reraise the exception, detach this thread, and
205         * wait for the fireworks. Die even more blatantly after a minute
206         * if the gentler attempt doesn't do the trick.
207         *
208         * The GetJavaVM function isn't on the "approved" list of JNI calls
209         * that can be made while an exception is pending, so we want to
210         * get the VM ptr, throw the exception, and then detach the thread.
211         */
212        JavaVM* vm = jnienv_to_javavm(env);
213        env->Throw(excep);
214        vm->DetachCurrentThread();
215        sleep(60);
216        ALOGE("Forcefully exiting");
217        exit(1);
218        *((int *) 1) = 1;
219    }
220
221bail:
222    /* discard local refs created for us by VM */
223    env->DeleteLocalRef(tagstr);
224    env->DeleteLocalRef(msgstr);
225}
226
227class JavaBBinderHolder;
228
229class JavaBBinder : public BBinder
230{
231public:
232    JavaBBinder(JNIEnv* env, jobject object)
233        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
234    {
235        ALOGV("Creating JavaBBinder %p\n", this);
236        android_atomic_inc(&gNumLocalRefs);
237        incRefsCreated(env);
238    }
239
240    bool    checkSubclass(const void* subclassID) const
241    {
242        return subclassID == &gBinderOffsets;
243    }
244
245    jobject object() const
246    {
247        return mObject;
248    }
249
250protected:
251    virtual ~JavaBBinder()
252    {
253        ALOGV("Destroying JavaBBinder %p\n", this);
254        android_atomic_dec(&gNumLocalRefs);
255        JNIEnv* env = javavm_to_jnienv(mVM);
256        env->DeleteGlobalRef(mObject);
257    }
258
259    virtual status_t onTransact(
260        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
261    {
262        JNIEnv* env = javavm_to_jnienv(mVM);
263
264        ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
265
266        IPCThreadState* thread_state = IPCThreadState::self();
267        const int strict_policy_before = thread_state->getStrictModePolicy();
268        thread_state->setLastTransactionBinderFlags(flags);
269
270        //printf("Transact from %p to Java code sending: ", this);
271        //data.print();
272        //printf("\n");
273        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
274            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
275        jthrowable excep = env->ExceptionOccurred();
276
277        if (excep) {
278            report_exception(env, excep,
279                "*** Uncaught remote exception!  "
280                "(Exceptions are not yet supported across processes.)");
281            res = JNI_FALSE;
282
283            /* clean up JNI local ref -- we don't return to Java code */
284            env->DeleteLocalRef(excep);
285        }
286
287        // Restore the Java binder thread's state if it changed while
288        // processing a call (as it would if the Parcel's header had a
289        // new policy mask and Parcel.enforceInterface() changed
290        // it...)
291        const int strict_policy_after = thread_state->getStrictModePolicy();
292        if (strict_policy_after != strict_policy_before) {
293            // Our thread-local...
294            thread_state->setStrictModePolicy(strict_policy_before);
295            // And the Java-level thread-local...
296            set_dalvik_blockguard_policy(env, strict_policy_before);
297        }
298
299        jthrowable excep2 = env->ExceptionOccurred();
300        if (excep2) {
301            report_exception(env, excep2,
302                "*** Uncaught exception in onBinderStrictModePolicyChange");
303            /* clean up JNI local ref -- we don't return to Java code */
304            env->DeleteLocalRef(excep2);
305        }
306
307        // Need to always call through the native implementation of
308        // SYSPROPS_TRANSACTION.
309        if (code == SYSPROPS_TRANSACTION) {
310            BBinder::onTransact(code, data, reply, flags);
311        }
312
313        //aout << "onTransact to Java code; result=" << res << endl
314        //    << "Transact from " << this << " to Java code returning "
315        //    << reply << ": " << *reply << endl;
316        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
317    }
318
319    virtual status_t dump(int fd, const Vector<String16>& args)
320    {
321        return 0;
322    }
323
324private:
325    JavaVM* const   mVM;
326    jobject const   mObject;
327};
328
329// ----------------------------------------------------------------------------
330
331class JavaBBinderHolder : public RefBase
332{
333public:
334    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
335    {
336        AutoMutex _l(mLock);
337        sp<JavaBBinder> b = mBinder.promote();
338        if (b == NULL) {
339            b = new JavaBBinder(env, obj);
340            mBinder = b;
341            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
342                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
343        }
344
345        return b;
346    }
347
348    sp<JavaBBinder> getExisting()
349    {
350        AutoMutex _l(mLock);
351        return mBinder.promote();
352    }
353
354private:
355    Mutex           mLock;
356    wp<JavaBBinder> mBinder;
357};
358
359// ----------------------------------------------------------------------------
360
361// Per-IBinder death recipient bookkeeping.  This is how we reconcile local jobject
362// death recipient references passed in through JNI with the permanent corresponding
363// JavaDeathRecipient objects.
364
365class JavaDeathRecipient;
366
367class DeathRecipientList : public RefBase {
368    List< sp<JavaDeathRecipient> > mList;
369    Mutex mLock;
370
371public:
372    DeathRecipientList();
373    ~DeathRecipientList();
374
375    void add(const sp<JavaDeathRecipient>& recipient);
376    void remove(const sp<JavaDeathRecipient>& recipient);
377    sp<JavaDeathRecipient> find(jobject recipient);
378};
379
380// ----------------------------------------------------------------------------
381
382class JavaDeathRecipient : public IBinder::DeathRecipient
383{
384public:
385    JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
386        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
387          mObjectWeak(NULL), mList(list)
388    {
389        // These objects manage their own lifetimes so are responsible for final bookkeeping.
390        // The list holds a strong reference to this object.
391        LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
392        list->add(this);
393
394        android_atomic_inc(&gNumDeathRefs);
395        incRefsCreated(env);
396    }
397
398    void binderDied(const wp<IBinder>& who)
399    {
400        LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
401        if (mObject != NULL) {
402            JNIEnv* env = javavm_to_jnienv(mVM);
403
404            env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
405                    gBinderProxyOffsets.mSendDeathNotice, mObject);
406            jthrowable excep = env->ExceptionOccurred();
407            if (excep) {
408                report_exception(env, excep,
409                        "*** Uncaught exception returned from death notification!");
410            }
411
412            // Demote from strong ref to weak after binderDied() has been delivered,
413            // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
414            mObjectWeak = env->NewWeakGlobalRef(mObject);
415            env->DeleteGlobalRef(mObject);
416            mObject = NULL;
417        }
418    }
419
420    void clearReference()
421    {
422        sp<DeathRecipientList> list = mList.promote();
423        if (list != NULL) {
424            LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
425            list->remove(this);
426        } else {
427            LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
428        }
429    }
430
431    bool matches(jobject obj) {
432        bool result;
433        JNIEnv* env = javavm_to_jnienv(mVM);
434
435        if (mObject != NULL) {
436            result = env->IsSameObject(obj, mObject);
437        } else {
438            jobject me = env->NewLocalRef(mObjectWeak);
439            result = env->IsSameObject(obj, me);
440            env->DeleteLocalRef(me);
441        }
442        return result;
443    }
444
445    void warnIfStillLive() {
446        if (mObject != NULL) {
447            // Okay, something is wrong -- we have a hard reference to a live death
448            // recipient on the VM side, but the list is being torn down.
449            JNIEnv* env = javavm_to_jnienv(mVM);
450            ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
451            ScopedLocalRef<jstring> nameRef(env,
452                    (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
453            ScopedUtfChars nameUtf(env, nameRef.get());
454            if (nameUtf.c_str() != NULL) {
455                ALOGW("BinderProxy is being destroyed but the application did not call "
456                        "unlinkToDeath to unlink all of its death recipients beforehand.  "
457                        "Releasing leaked death recipient: %s", nameUtf.c_str());
458            } else {
459                ALOGW("BinderProxy being destroyed; unable to get DR object name");
460                env->ExceptionClear();
461            }
462        }
463    }
464
465protected:
466    virtual ~JavaDeathRecipient()
467    {
468        //ALOGI("Removing death ref: recipient=%p\n", mObject);
469        android_atomic_dec(&gNumDeathRefs);
470        JNIEnv* env = javavm_to_jnienv(mVM);
471        if (mObject != NULL) {
472            env->DeleteGlobalRef(mObject);
473        } else {
474            env->DeleteWeakGlobalRef(mObjectWeak);
475        }
476    }
477
478private:
479    JavaVM* const mVM;
480    jobject mObject;
481    jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
482    wp<DeathRecipientList> mList;
483};
484
485// ----------------------------------------------------------------------------
486
487DeathRecipientList::DeathRecipientList() {
488    LOGDEATH("New DRL @ %p", this);
489}
490
491DeathRecipientList::~DeathRecipientList() {
492    LOGDEATH("Destroy DRL @ %p", this);
493    AutoMutex _l(mLock);
494
495    // Should never happen -- the JavaDeathRecipient objects that have added themselves
496    // to the list are holding references on the list object.  Only when they are torn
497    // down can the list header be destroyed.
498    if (mList.size() > 0) {
499        List< sp<JavaDeathRecipient> >::iterator iter;
500        for (iter = mList.begin(); iter != mList.end(); iter++) {
501            (*iter)->warnIfStillLive();
502        }
503    }
504}
505
506void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
507    AutoMutex _l(mLock);
508
509    LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
510    mList.push_back(recipient);
511}
512
513void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
514    AutoMutex _l(mLock);
515
516    List< sp<JavaDeathRecipient> >::iterator iter;
517    for (iter = mList.begin(); iter != mList.end(); iter++) {
518        if (*iter == recipient) {
519            LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
520            mList.erase(iter);
521            return;
522        }
523    }
524}
525
526sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
527    AutoMutex _l(mLock);
528
529    List< sp<JavaDeathRecipient> >::iterator iter;
530    for (iter = mList.begin(); iter != mList.end(); iter++) {
531        if ((*iter)->matches(recipient)) {
532            return *iter;
533        }
534    }
535    return NULL;
536}
537
538// ----------------------------------------------------------------------------
539
540namespace android {
541
542static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
543{
544    android_atomic_dec(&gNumProxyRefs);
545    JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
546    env->DeleteGlobalRef((jobject)obj);
547}
548
549static Mutex mProxyLock;
550
551jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
552{
553    if (val == NULL) return NULL;
554
555    if (val->checkSubclass(&gBinderOffsets)) {
556        // One of our own!
557        jobject object = static_cast<JavaBBinder*>(val.get())->object();
558        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
559        return object;
560    }
561
562    // For the rest of the function we will hold this lock, to serialize
563    // looking/creation of Java proxies for native Binder proxies.
564    AutoMutex _l(mProxyLock);
565
566    // Someone else's...  do we know about it?
567    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
568    if (object != NULL) {
569        jobject res = jniGetReferent(env, object);
570        if (res != NULL) {
571            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
572            return res;
573        }
574        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
575        android_atomic_dec(&gNumProxyRefs);
576        val->detachObject(&gBinderProxyOffsets);
577        env->DeleteGlobalRef(object);
578    }
579
580    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
581    if (object != NULL) {
582        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
583        // The proxy holds a reference to the native object.
584        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
585        val->incStrong((void*)javaObjectForIBinder);
586
587        // The native object needs to hold a weak reference back to the
588        // proxy, so we can retrieve the same proxy if it is still active.
589        jobject refObject = env->NewGlobalRef(
590                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
591        val->attachObject(&gBinderProxyOffsets, refObject,
592                jnienv_to_javavm(env), proxy_cleanup);
593
594        // Also remember the death recipients registered on this proxy
595        sp<DeathRecipientList> drl = new DeathRecipientList;
596        drl->incStrong((void*)javaObjectForIBinder);
597        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
598
599        // Note that a new object reference has been created.
600        android_atomic_inc(&gNumProxyRefs);
601        incRefsCreated(env);
602    }
603
604    return object;
605}
606
607sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
608{
609    if (obj == NULL) return NULL;
610
611    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
612        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
613            env->GetLongField(obj, gBinderOffsets.mObject);
614        return jbh != NULL ? jbh->get(env, obj) : NULL;
615    }
616
617    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
618        return (IBinder*)
619            env->GetLongField(obj, gBinderProxyOffsets.mObject);
620    }
621
622    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
623    return NULL;
624}
625
626jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
627{
628    return env->NewObject(
629            gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
630}
631
632void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
633{
634    // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
635    // to sync our state back to it.  See the comments in StrictMode.java.
636    env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
637                              gStrictModeCallbackOffsets.mCallback,
638                              strict_policy);
639}
640
641void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
642        bool canThrowRemoteException)
643{
644    switch (err) {
645        case UNKNOWN_ERROR:
646            jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
647            break;
648        case NO_MEMORY:
649            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
650            break;
651        case INVALID_OPERATION:
652            jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
653            break;
654        case BAD_VALUE:
655            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
656            break;
657        case BAD_INDEX:
658            jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
659            break;
660        case BAD_TYPE:
661            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
662            break;
663        case NAME_NOT_FOUND:
664            jniThrowException(env, "java/util/NoSuchElementException", NULL);
665            break;
666        case PERMISSION_DENIED:
667            jniThrowException(env, "java/lang/SecurityException", NULL);
668            break;
669        case NOT_ENOUGH_DATA:
670            jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
671            break;
672        case NO_INIT:
673            jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
674            break;
675        case ALREADY_EXISTS:
676            jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
677            break;
678        case DEAD_OBJECT:
679            // DeadObjectException is a checked exception, only throw from certain methods.
680            jniThrowException(env, canThrowRemoteException
681                    ? "android/os/DeadObjectException"
682                            : "java/lang/RuntimeException", NULL);
683            break;
684        case UNKNOWN_TRANSACTION:
685            jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
686            break;
687        case FAILED_TRANSACTION:
688            ALOGE("!!! FAILED BINDER TRANSACTION !!!");
689            // TransactionTooLargeException is a checked exception, only throw from certain methods.
690            // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
691            //        but it is not the only one.  The Binder driver can return BR_FAILED_REPLY
692            //        for other reasons also, such as if the transaction is malformed or
693            //        refers to an FD that has been closed.  We should change the driver
694            //        to enable us to distinguish these cases in the future.
695            jniThrowException(env, canThrowRemoteException
696                    ? "android/os/TransactionTooLargeException"
697                            : "java/lang/RuntimeException", NULL);
698            break;
699        case FDS_NOT_ALLOWED:
700            jniThrowException(env, "java/lang/RuntimeException",
701                    "Not allowed to write file descriptors here");
702            break;
703        case -EBADF:
704            jniThrowException(env, "java/lang/RuntimeException",
705                    "Bad file descriptor");
706            break;
707        case -ENFILE:
708            jniThrowException(env, "java/lang/RuntimeException",
709                    "File table overflow");
710            break;
711        case -EMFILE:
712            jniThrowException(env, "java/lang/RuntimeException",
713                    "Too many open files");
714            break;
715        case -EFBIG:
716            jniThrowException(env, "java/lang/RuntimeException",
717                    "File too large");
718            break;
719        case -ENOSPC:
720            jniThrowException(env, "java/lang/RuntimeException",
721                    "No space left on device");
722            break;
723        case -ESPIPE:
724            jniThrowException(env, "java/lang/RuntimeException",
725                    "Illegal seek");
726            break;
727        case -EROFS:
728            jniThrowException(env, "java/lang/RuntimeException",
729                    "Read-only file system");
730            break;
731        case -EMLINK:
732            jniThrowException(env, "java/lang/RuntimeException",
733                    "Too many links");
734            break;
735        default:
736            ALOGE("Unknown binder error code. 0x%" PRIx32, err);
737            String8 msg;
738            msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
739            // RemoteException is a checked exception, only throw from certain methods.
740            jniThrowException(env, canThrowRemoteException
741                    ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
742            break;
743    }
744}
745
746}
747
748// ----------------------------------------------------------------------------
749
750static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
751{
752    return IPCThreadState::self()->getCallingPid();
753}
754
755static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
756{
757    return IPCThreadState::self()->getCallingUid();
758}
759
760static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
761{
762    return IPCThreadState::self()->clearCallingIdentity();
763}
764
765static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
766{
767    // XXX temporary sanity check to debug crashes.
768    int uid = (int)(token>>32);
769    if (uid > 0 && uid < 999) {
770        // In Android currently there are no uids in this range.
771        char buf[128];
772        sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
773        jniThrowException(env, "java/lang/IllegalStateException", buf);
774        return;
775    }
776    IPCThreadState::self()->restoreCallingIdentity(token);
777}
778
779static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
780{
781    IPCThreadState::self()->setStrictModePolicy(policyMask);
782}
783
784static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
785{
786    return IPCThreadState::self()->getStrictModePolicy();
787}
788
789static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
790{
791    IPCThreadState::self()->flushCommands();
792}
793
794static void android_os_Binder_init(JNIEnv* env, jobject obj)
795{
796    JavaBBinderHolder* jbh = new JavaBBinderHolder();
797    if (jbh == NULL) {
798        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
799        return;
800    }
801    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
802    jbh->incStrong((void*)android_os_Binder_init);
803    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
804}
805
806static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
807{
808    JavaBBinderHolder* jbh = (JavaBBinderHolder*)
809        env->GetLongField(obj, gBinderOffsets.mObject);
810    if (jbh != NULL) {
811        env->SetLongField(obj, gBinderOffsets.mObject, 0);
812        ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
813        jbh->decStrong((void*)android_os_Binder_init);
814    } else {
815        // Encountering an uninitialized binder is harmless.  All it means is that
816        // the Binder was only partially initialized when its finalizer ran and called
817        // destroy().  The Binder could be partially initialized for several reasons.
818        // For example, a Binder subclass constructor might have thrown an exception before
819        // it could delegate to its superclass's constructor.  Consequently init() would
820        // not have been called and the holder pointer would remain NULL.
821        ALOGV("Java Binder %p: ignoring uninitialized binder", obj);
822    }
823}
824
825// ----------------------------------------------------------------------------
826
827static const JNINativeMethod gBinderMethods[] = {
828     /* name, signature, funcPtr */
829    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
830    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
831    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
832    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
833    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
834    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
835    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
836    { "init", "()V", (void*)android_os_Binder_init },
837    { "destroy", "()V", (void*)android_os_Binder_destroy }
838};
839
840const char* const kBinderPathName = "android/os/Binder";
841
842static int int_register_android_os_Binder(JNIEnv* env)
843{
844    jclass clazz;
845
846    clazz = env->FindClass(kBinderPathName);
847    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
848
849    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
850    gBinderOffsets.mExecTransact
851        = env->GetMethodID(clazz, "execTransact", "(IJJI)Z");
852    assert(gBinderOffsets.mExecTransact);
853
854    gBinderOffsets.mObject
855        = env->GetFieldID(clazz, "mObject", "J");
856    assert(gBinderOffsets.mObject);
857
858    return AndroidRuntime::registerNativeMethods(
859        env, kBinderPathName,
860        gBinderMethods, NELEM(gBinderMethods));
861}
862
863// ****************************************************************************
864// ****************************************************************************
865// ****************************************************************************
866
867namespace android {
868
869jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
870{
871    return gNumLocalRefs;
872}
873
874jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
875{
876    return gNumProxyRefs;
877}
878
879jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
880{
881    return gNumDeathRefs;
882}
883
884}
885
886// ****************************************************************************
887// ****************************************************************************
888// ****************************************************************************
889
890static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
891{
892    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
893    return javaObjectForIBinder(env, b);
894}
895
896static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
897{
898    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
899    android::IPCThreadState::self()->joinThreadPool();
900}
901
902static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
903        jobject clazz, jboolean disable)
904{
905    IPCThreadState::disableBackgroundScheduling(disable ? true : false);
906}
907
908static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
909{
910    ALOGV("Gc has executed, clearing binder ops");
911    android_atomic_and(0, &gNumRefsCreated);
912}
913
914// ----------------------------------------------------------------------------
915
916static const JNINativeMethod gBinderInternalMethods[] = {
917     /* name, signature, funcPtr */
918    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
919    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
920    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
921    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
922};
923
924const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
925
926static int int_register_android_os_BinderInternal(JNIEnv* env)
927{
928    jclass clazz;
929
930    clazz = env->FindClass(kBinderInternalPathName);
931    LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
932
933    gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
934    gBinderInternalOffsets.mForceGc
935        = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
936    assert(gBinderInternalOffsets.mForceGc);
937
938    return AndroidRuntime::registerNativeMethods(
939        env, kBinderInternalPathName,
940        gBinderInternalMethods, NELEM(gBinderInternalMethods));
941}
942
943// ****************************************************************************
944// ****************************************************************************
945// ****************************************************************************
946
947static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
948{
949    IBinder* target = (IBinder*)
950        env->GetLongField(obj, gBinderProxyOffsets.mObject);
951    if (target == NULL) {
952        return JNI_FALSE;
953    }
954    status_t err = target->pingBinder();
955    return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
956}
957
958static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
959{
960    IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
961    if (target != NULL) {
962        const String16& desc = target->getInterfaceDescriptor();
963        return env->NewString(desc.string(), desc.size());
964    }
965    jniThrowException(env, "java/lang/RuntimeException",
966            "No binder found for object");
967    return NULL;
968}
969
970static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
971{
972    IBinder* target = (IBinder*)
973        env->GetLongField(obj, gBinderProxyOffsets.mObject);
974    if (target == NULL) {
975        return JNI_FALSE;
976    }
977    bool alive = target->isBinderAlive();
978    return alive ? JNI_TRUE : JNI_FALSE;
979}
980
981static int getprocname(pid_t pid, char *buf, size_t len) {
982    char filename[32];
983    FILE *f;
984
985    snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
986    f = fopen(filename, "r");
987    if (!f) {
988        *buf = '\0';
989        return 1;
990    }
991    if (!fgets(buf, len, f)) {
992        *buf = '\0';
993        fclose(f);
994        return 2;
995    }
996    fclose(f);
997    return 0;
998}
999
1000static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1001    jint len = strlen(str);
1002    int space_needed = 1 + sizeof(len) + len;
1003    if (end - *pos < space_needed) {
1004        ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
1005             end - *pos, space_needed);
1006        return false;
1007    }
1008    **pos = EVENT_TYPE_STRING;
1009    (*pos)++;
1010    memcpy(*pos, &len, sizeof(len));
1011    *pos += sizeof(len);
1012    memcpy(*pos, str, len);
1013    *pos += len;
1014    return true;
1015}
1016
1017static bool push_eventlog_int(char** pos, const char* end, jint val) {
1018    int space_needed = 1 + sizeof(val);
1019    if (end - *pos < space_needed) {
1020        ALOGW("not enough space for int.  remain=%" PRIdPTR "; needed=%d",
1021             end - *pos, space_needed);
1022        return false;
1023    }
1024    **pos = EVENT_TYPE_INT;
1025    (*pos)++;
1026    memcpy(*pos, &val, sizeof(val));
1027    *pos += sizeof(val);
1028    return true;
1029}
1030
1031// From frameworks/base/core/java/android/content/EventLogTags.logtags:
1032#define ENABLE_BINDER_SAMPLE 0
1033#define LOGTAG_BINDER_OPERATION 52004
1034
1035static void conditionally_log_binder_call(int64_t start_millis,
1036                                          IBinder* target, jint code) {
1037    int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1038
1039    int sample_percent;
1040    if (duration_ms >= 500) {
1041        sample_percent = 100;
1042    } else {
1043        sample_percent = 100 * duration_ms / 500;
1044        if (sample_percent == 0) {
1045            return;
1046        }
1047        if (sample_percent < (random() % 100 + 1)) {
1048            return;
1049        }
1050    }
1051
1052    char process_name[40];
1053    getprocname(getpid(), process_name, sizeof(process_name));
1054    String8 desc(target->getInterfaceDescriptor());
1055
1056    char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1057    buf[0] = EVENT_TYPE_LIST;
1058    buf[1] = 5;
1059    char* pos = &buf[2];
1060    char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1];  // leave room for final \n
1061    if (!push_eventlog_string(&pos, end, desc.string())) return;
1062    if (!push_eventlog_int(&pos, end, code)) return;
1063    if (!push_eventlog_int(&pos, end, duration_ms)) return;
1064    if (!push_eventlog_string(&pos, end, process_name)) return;
1065    if (!push_eventlog_int(&pos, end, sample_percent)) return;
1066    *(pos++) = '\n';   // conventional with EVENT_TYPE_LIST apparently.
1067    android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1068}
1069
1070// We only measure binder call durations to potentially log them if
1071// we're on the main thread.  Unfortunately sim-eng doesn't seem to
1072// have gettid, so we just ignore this and don't log if we can't
1073// get the thread id.
1074static bool should_time_binder_calls() {
1075#ifdef HAVE_GETTID
1076  return (getpid() == androidGetTid());
1077#else
1078#warning no gettid(), so not logging Binder calls...
1079  return false;
1080#endif
1081}
1082
1083static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1084        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1085{
1086    if (dataObj == NULL) {
1087        jniThrowNullPointerException(env, NULL);
1088        return JNI_FALSE;
1089    }
1090
1091    Parcel* data = parcelForJavaObject(env, dataObj);
1092    if (data == NULL) {
1093        return JNI_FALSE;
1094    }
1095    Parcel* reply = parcelForJavaObject(env, replyObj);
1096    if (reply == NULL && replyObj != NULL) {
1097        return JNI_FALSE;
1098    }
1099
1100    IBinder* target = (IBinder*)
1101        env->GetLongField(obj, gBinderProxyOffsets.mObject);
1102    if (target == NULL) {
1103        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1104        return JNI_FALSE;
1105    }
1106
1107    ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
1108            target, obj, code);
1109
1110#if ENABLE_BINDER_SAMPLE
1111    // Only log the binder call duration for things on the Java-level main thread.
1112    // But if we don't
1113    const bool time_binder_calls = should_time_binder_calls();
1114
1115    int64_t start_millis;
1116    if (time_binder_calls) {
1117        start_millis = uptimeMillis();
1118    }
1119#endif
1120    //printf("Transact from Java code to %p sending: ", target); data->print();
1121    status_t err = target->transact(code, *data, reply, flags);
1122    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1123#if ENABLE_BINDER_SAMPLE
1124    if (time_binder_calls) {
1125        conditionally_log_binder_call(start_millis, target, code);
1126    }
1127#endif
1128
1129    if (err == NO_ERROR) {
1130        return JNI_TRUE;
1131    } else if (err == UNKNOWN_TRANSACTION) {
1132        return JNI_FALSE;
1133    }
1134
1135    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1136    return JNI_FALSE;
1137}
1138
1139static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1140        jobject recipient, jint flags) // throws RemoteException
1141{
1142    if (recipient == NULL) {
1143        jniThrowNullPointerException(env, NULL);
1144        return;
1145    }
1146
1147    IBinder* target = (IBinder*)
1148        env->GetLongField(obj, gBinderProxyOffsets.mObject);
1149    if (target == NULL) {
1150        ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1151        assert(false);
1152    }
1153
1154    LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1155
1156    if (!target->localBinder()) {
1157        DeathRecipientList* list = (DeathRecipientList*)
1158                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
1159        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
1160        status_t err = target->linkToDeath(jdr, NULL, flags);
1161        if (err != NO_ERROR) {
1162            // Failure adding the death recipient, so clear its reference
1163            // now.
1164            jdr->clearReference();
1165            signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1166        }
1167    }
1168}
1169
1170static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1171                                                 jobject recipient, jint flags)
1172{
1173    jboolean res = JNI_FALSE;
1174    if (recipient == NULL) {
1175        jniThrowNullPointerException(env, NULL);
1176        return res;
1177    }
1178
1179    IBinder* target = (IBinder*)
1180        env->GetLongField(obj, gBinderProxyOffsets.mObject);
1181    if (target == NULL) {
1182        ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1183        return JNI_FALSE;
1184    }
1185
1186    LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1187
1188    if (!target->localBinder()) {
1189        status_t err = NAME_NOT_FOUND;
1190
1191        // If we find the matching recipient, proceed to unlink using that
1192        DeathRecipientList* list = (DeathRecipientList*)
1193                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
1194        sp<JavaDeathRecipient> origJDR = list->find(recipient);
1195        LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
1196        if (origJDR != NULL) {
1197            wp<IBinder::DeathRecipient> dr;
1198            err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1199            if (err == NO_ERROR && dr != NULL) {
1200                sp<IBinder::DeathRecipient> sdr = dr.promote();
1201                JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1202                if (jdr != NULL) {
1203                    jdr->clearReference();
1204                }
1205            }
1206        }
1207
1208        if (err == NO_ERROR || err == DEAD_OBJECT) {
1209            res = JNI_TRUE;
1210        } else {
1211            jniThrowException(env, "java/util/NoSuchElementException",
1212                              "Death link does not exist");
1213        }
1214    }
1215
1216    return res;
1217}
1218
1219static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
1220{
1221    IBinder* b = (IBinder*)
1222            env->GetLongField(obj, gBinderProxyOffsets.mObject);
1223    DeathRecipientList* drl = (DeathRecipientList*)
1224            env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
1225
1226    LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
1227    env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
1228    env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
1229    drl->decStrong((void*)javaObjectForIBinder);
1230    b->decStrong((void*)javaObjectForIBinder);
1231
1232    IPCThreadState::self()->flushCommands();
1233}
1234
1235// ----------------------------------------------------------------------------
1236
1237static const JNINativeMethod gBinderProxyMethods[] = {
1238     /* name, signature, funcPtr */
1239    {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
1240    {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1241    {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1242    {"transact",            "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1243    {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1244    {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1245    {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
1246};
1247
1248const char* const kBinderProxyPathName = "android/os/BinderProxy";
1249
1250static int int_register_android_os_BinderProxy(JNIEnv* env)
1251{
1252    jclass clazz;
1253
1254    clazz = env->FindClass("java/lang/Error");
1255    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
1256    gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1257
1258    clazz = env->FindClass(kBinderProxyPathName);
1259    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
1260
1261    gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1262    gBinderProxyOffsets.mConstructor
1263        = env->GetMethodID(clazz, "<init>", "()V");
1264    assert(gBinderProxyOffsets.mConstructor);
1265    gBinderProxyOffsets.mSendDeathNotice
1266        = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
1267    assert(gBinderProxyOffsets.mSendDeathNotice);
1268
1269    gBinderProxyOffsets.mObject
1270        = env->GetFieldID(clazz, "mObject", "J");
1271    assert(gBinderProxyOffsets.mObject);
1272    gBinderProxyOffsets.mSelf
1273        = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
1274    assert(gBinderProxyOffsets.mSelf);
1275    gBinderProxyOffsets.mOrgue
1276        = env->GetFieldID(clazz, "mOrgue", "J");
1277    assert(gBinderProxyOffsets.mOrgue);
1278
1279    clazz = env->FindClass("java/lang/Class");
1280    LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class");
1281    gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");
1282    assert(gClassOffsets.mGetName);
1283
1284    return AndroidRuntime::registerNativeMethods(
1285        env, kBinderProxyPathName,
1286        gBinderProxyMethods, NELEM(gBinderProxyMethods));
1287}
1288
1289// ****************************************************************************
1290// ****************************************************************************
1291// ****************************************************************************
1292
1293int register_android_os_Binder(JNIEnv* env)
1294{
1295    if (int_register_android_os_Binder(env) < 0)
1296        return -1;
1297    if (int_register_android_os_BinderInternal(env) < 0)
1298        return -1;
1299    if (int_register_android_os_BinderProxy(env) < 0)
1300        return -1;
1301
1302    jclass clazz;
1303
1304    clazz = env->FindClass("android/util/Log");
1305    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log");
1306    gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1307    gLogOffsets.mLogE = env->GetStaticMethodID(
1308        clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1309    assert(gLogOffsets.mLogE);
1310
1311    clazz = env->FindClass("android/os/ParcelFileDescriptor");
1312    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
1313    gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1314    gParcelFileDescriptorOffsets.mConstructor
1315        = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
1316
1317    clazz = env->FindClass("android/os/StrictMode");
1318    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode");
1319    gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1320    gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID(
1321        clazz, "onBinderStrictModePolicyChange", "(I)V");
1322    LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL,
1323                 "Unable to find strict mode callback.");
1324
1325    return 0;
1326}
1327