OSDN Git Service

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