Home | History | Annotate | Download | only in jni
      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_util_Binder.h"
     21 #include "JNIHelp.h"
     22 
     23 #include <fcntl.h>
     24 #include <stdio.h>
     25 #include <sys/stat.h>
     26 #include <sys/types.h>
     27 #include <unistd.h>
     28 
     29 #include <utils/Atomic.h>
     30 #include <binder/IInterface.h>
     31 #include <binder/IPCThreadState.h>
     32 #include <utils/Log.h>
     33 #include <utils/SystemClock.h>
     34 #include <utils/List.h>
     35 #include <utils/KeyedVector.h>
     36 #include <cutils/logger.h>
     37 #include <binder/Parcel.h>
     38 #include <binder/ProcessState.h>
     39 #include <binder/IServiceManager.h>
     40 #include <utils/threads.h>
     41 #include <utils/String8.h>
     42 
     43 #include <ScopedUtfChars.h>
     44 #include <ScopedLocalRef.h>
     45 
     46 #include <android_runtime/AndroidRuntime.h>
     47 
     48 //#undef LOGV
     49 //#define LOGV(...) fprintf(stderr, __VA_ARGS__)
     50 
     51 #define DEBUG_DEATH 0
     52 #if DEBUG_DEATH
     53 #define LOGDEATH LOGD
     54 #else
     55 #define LOGDEATH LOGV
     56 #endif
     57 
     58 using namespace android;
     59 
     60 // ----------------------------------------------------------------------------
     61 
     62 static struct bindernative_offsets_t
     63 {
     64     // Class state.
     65     jclass mClass;
     66     jmethodID mExecTransact;
     67 
     68     // Object state.
     69     jfieldID mObject;
     70 
     71 } gBinderOffsets;
     72 
     73 // ----------------------------------------------------------------------------
     74 
     75 static struct binderinternal_offsets_t
     76 {
     77     // Class state.
     78     jclass mClass;
     79     jmethodID mForceGc;
     80 
     81 } gBinderInternalOffsets;
     82 
     83 // ----------------------------------------------------------------------------
     84 
     85 static struct debug_offsets_t
     86 {
     87     // Class state.
     88     jclass mClass;
     89 
     90 } gDebugOffsets;
     91 
     92 // ----------------------------------------------------------------------------
     93 
     94 static struct weakreference_offsets_t
     95 {
     96     // Class state.
     97     jclass mClass;
     98     jmethodID mGet;
     99 
    100 } gWeakReferenceOffsets;
    101 
    102 static struct error_offsets_t
    103 {
    104     jclass mClass;
    105 } gErrorOffsets;
    106 
    107 // ----------------------------------------------------------------------------
    108 
    109 static struct binderproxy_offsets_t
    110 {
    111     // Class state.
    112     jclass mClass;
    113     jmethodID mConstructor;
    114     jmethodID mSendDeathNotice;
    115 
    116     // Object state.
    117     jfieldID mObject;
    118     jfieldID mSelf;
    119     jfieldID mOrgue;
    120 
    121 } gBinderProxyOffsets;
    122 
    123 static struct class_offsets_t
    124 {
    125     jmethodID mGetName;
    126 } gClassOffsets;
    127 
    128 // ----------------------------------------------------------------------------
    129 
    130 static struct parcel_offsets_t
    131 {
    132     jfieldID mObject;
    133     jfieldID mOwnObject;
    134 } gParcelOffsets;
    135 
    136 static struct log_offsets_t
    137 {
    138     // Class state.
    139     jclass mClass;
    140     jmethodID mLogE;
    141 } gLogOffsets;
    142 
    143 static struct parcel_file_descriptor_offsets_t
    144 {
    145     jclass mClass;
    146     jmethodID mConstructor;
    147 } gParcelFileDescriptorOffsets;
    148 
    149 static struct strict_mode_callback_offsets_t
    150 {
    151     jclass mClass;
    152     jmethodID mCallback;
    153 } gStrictModeCallbackOffsets;
    154 
    155 // ****************************************************************************
    156 // ****************************************************************************
    157 // ****************************************************************************
    158 
    159 static volatile int32_t gNumRefsCreated = 0;
    160 static volatile int32_t gNumProxyRefs = 0;
    161 static volatile int32_t gNumLocalRefs = 0;
    162 static volatile int32_t gNumDeathRefs = 0;
    163 
    164 static void incRefsCreated(JNIEnv* env)
    165 {
    166     int old = android_atomic_inc(&gNumRefsCreated);
    167     if (old == 200) {
    168         android_atomic_and(0, &gNumRefsCreated);
    169         env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
    170                 gBinderInternalOffsets.mForceGc);
    171     } else {
    172         LOGV("Now have %d binder ops", old);
    173     }
    174 }
    175 
    176 static JavaVM* jnienv_to_javavm(JNIEnv* env)
    177 {
    178     JavaVM* vm;
    179     return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
    180 }
    181 
    182 static JNIEnv* javavm_to_jnienv(JavaVM* vm)
    183 {
    184     JNIEnv* env;
    185     return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
    186 }
    187 
    188 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
    189 {
    190     env->ExceptionClear();
    191 
    192     jstring tagstr = env->NewStringUTF(LOG_TAG);
    193     jstring msgstr = env->NewStringUTF(msg);
    194 
    195     if ((tagstr == NULL) || (msgstr == NULL)) {
    196         env->ExceptionClear();      /* assume exception (OOM?) was thrown */
    197         LOGE("Unable to call Log.e()\n");
    198         LOGE("%s", msg);
    199         goto bail;
    200     }
    201 
    202     env->CallStaticIntMethod(
    203         gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
    204     if (env->ExceptionCheck()) {
    205         /* attempting to log the failure has failed */
    206         LOGW("Failed trying to log exception, msg='%s'\n", msg);
    207         env->ExceptionClear();
    208     }
    209 
    210     if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
    211         /*
    212          * It's an Error: Reraise the exception, detach this thread, and
    213          * wait for the fireworks. Die even more blatantly after a minute
    214          * if the gentler attempt doesn't do the trick.
    215          *
    216          * The GetJavaVM function isn't on the "approved" list of JNI calls
    217          * that can be made while an exception is pending, so we want to
    218          * get the VM ptr, throw the exception, and then detach the thread.
    219          */
    220         JavaVM* vm = jnienv_to_javavm(env);
    221         env->Throw(excep);
    222         vm->DetachCurrentThread();
    223         sleep(60);
    224         LOGE("Forcefully exiting");
    225         exit(1);
    226         *((int *) 1) = 1;
    227     }
    228 
    229 bail:
    230     /* discard local refs created for us by VM */
    231     env->DeleteLocalRef(tagstr);
    232     env->DeleteLocalRef(msgstr);
    233 }
    234 
    235 static void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
    236 {
    237     // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
    238     // to sync our state back to it.  See the comments in StrictMode.java.
    239     env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
    240                               gStrictModeCallbackOffsets.mCallback,
    241                               strict_policy);
    242 }
    243 
    244 class JavaBBinderHolder;
    245 
    246 class JavaBBinder : public BBinder
    247 {
    248 public:
    249     JavaBBinder(JNIEnv* env, jobject object)
    250         : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    251     {
    252         LOGV("Creating JavaBBinder %p\n", this);
    253         android_atomic_inc(&gNumLocalRefs);
    254         incRefsCreated(env);
    255     }
    256 
    257     bool    checkSubclass(const void* subclassID) const
    258     {
    259         return subclassID == &gBinderOffsets;
    260     }
    261 
    262     jobject object() const
    263     {
    264         return mObject;
    265     }
    266 
    267 protected:
    268     virtual ~JavaBBinder()
    269     {
    270         LOGV("Destroying JavaBBinder %p\n", this);
    271         android_atomic_dec(&gNumLocalRefs);
    272         JNIEnv* env = javavm_to_jnienv(mVM);
    273         env->DeleteGlobalRef(mObject);
    274     }
    275 
    276     virtual status_t onTransact(
    277         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    278     {
    279         JNIEnv* env = javavm_to_jnienv(mVM);
    280 
    281         LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
    282 
    283         IPCThreadState* thread_state = IPCThreadState::self();
    284         const int strict_policy_before = thread_state->getStrictModePolicy();
    285         thread_state->setLastTransactionBinderFlags(flags);
    286 
    287         //printf("Transact from %p to Java code sending: ", this);
    288         //data.print();
    289         //printf("\n");
    290         jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
    291             code, (int32_t)&data, (int32_t)reply, flags);
    292         jthrowable excep = env->ExceptionOccurred();
    293 
    294         if (excep) {
    295             report_exception(env, excep,
    296                 "*** Uncaught remote exception!  "
    297                 "(Exceptions are not yet supported across processes.)");
    298             res = JNI_FALSE;
    299 
    300             /* clean up JNI local ref -- we don't return to Java code */
    301             env->DeleteLocalRef(excep);
    302         }
    303 
    304         // Restore the Java binder thread's state if it changed while
    305         // processing a call (as it would if the Parcel's header had a
    306         // new policy mask and Parcel.enforceInterface() changed
    307         // it...)
    308         const int strict_policy_after = thread_state->getStrictModePolicy();
    309         if (strict_policy_after != strict_policy_before) {
    310             // Our thread-local...
    311             thread_state->setStrictModePolicy(strict_policy_before);
    312             // And the Java-level thread-local...
    313             set_dalvik_blockguard_policy(env, strict_policy_before);
    314         }
    315 
    316         jthrowable excep2 = env->ExceptionOccurred();
    317         if (excep2) {
    318             report_exception(env, excep2,
    319                 "*** Uncaught exception in onBinderStrictModePolicyChange");
    320             /* clean up JNI local ref -- we don't return to Java code */
    321             env->DeleteLocalRef(excep2);
    322         }
    323 
    324         //aout << "onTransact to Java code; result=" << res << endl
    325         //    << "Transact from " << this << " to Java code returning "
    326         //    << reply << ": " << *reply << endl;
    327         return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
    328     }
    329 
    330     virtual status_t dump(int fd, const Vector<String16>& args)
    331     {
    332         return 0;
    333     }
    334 
    335 private:
    336     JavaVM* const   mVM;
    337     jobject const   mObject;
    338 };
    339 
    340 // ----------------------------------------------------------------------------
    341 
    342 class JavaBBinderHolder : public RefBase
    343 {
    344 public:
    345     sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    346     {
    347         AutoMutex _l(mLock);
    348         sp<JavaBBinder> b = mBinder.promote();
    349         if (b == NULL) {
    350             b = new JavaBBinder(env, obj);
    351             mBinder = b;
    352             LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
    353                  b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
    354         }
    355 
    356         return b;
    357     }
    358 
    359     sp<JavaBBinder> getExisting()
    360     {
    361         AutoMutex _l(mLock);
    362         return mBinder.promote();
    363     }
    364 
    365 private:
    366     Mutex           mLock;
    367     wp<JavaBBinder> mBinder;
    368 };
    369 
    370 // ----------------------------------------------------------------------------
    371 
    372 // Per-IBinder death recipient bookkeeping.  This is how we reconcile local jobject
    373 // death recipient references passed in through JNI with the permanent corresponding
    374 // JavaDeathRecipient objects.
    375 
    376 class JavaDeathRecipient;
    377 
    378 class DeathRecipientList : public RefBase {
    379     List< sp<JavaDeathRecipient> > mList;
    380     Mutex mLock;
    381 
    382 public:
    383     DeathRecipientList();
    384     ~DeathRecipientList();
    385 
    386     void add(const sp<JavaDeathRecipient>& recipient);
    387     void remove(const sp<JavaDeathRecipient>& recipient);
    388     sp<JavaDeathRecipient> find(jobject recipient);
    389 };
    390 
    391 // ----------------------------------------------------------------------------
    392 
    393 class JavaDeathRecipient : public IBinder::DeathRecipient
    394 {
    395 public:
    396     JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
    397         : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
    398           mObjectWeak(NULL), mList(list)
    399     {
    400         // These objects manage their own lifetimes so are responsible for final bookkeeping.
    401         // The list holds a strong reference to this object.
    402         LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
    403         list->add(this);
    404 
    405         android_atomic_inc(&gNumDeathRefs);
    406         incRefsCreated(env);
    407     }
    408 
    409     void binderDied(const wp<IBinder>& who)
    410     {
    411         LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
    412         if (mObject != NULL) {
    413             JNIEnv* env = javavm_to_jnienv(mVM);
    414 
    415             env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
    416                     gBinderProxyOffsets.mSendDeathNotice, mObject);
    417             jthrowable excep = env->ExceptionOccurred();
    418             if (excep) {
    419                 report_exception(env, excep,
    420                         "*** Uncaught exception returned from death notification!");
    421             }
    422 
    423             // Demote from strong ref to weak after binderDied() has been delivered,
    424             // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
    425             mObjectWeak = env->NewWeakGlobalRef(mObject);
    426             env->DeleteGlobalRef(mObject);
    427             mObject = NULL;
    428         }
    429     }
    430 
    431     void clearReference()
    432     {
    433         sp<DeathRecipientList> list = mList.promote();
    434         if (list != NULL) {
    435             LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
    436             list->remove(this);
    437         } else {
    438             LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
    439         }
    440     }
    441 
    442     bool matches(jobject obj) {
    443         bool result;
    444         JNIEnv* env = javavm_to_jnienv(mVM);
    445 
    446         if (mObject != NULL) {
    447             result = env->IsSameObject(obj, mObject);
    448         } else {
    449             jobject me = env->NewLocalRef(mObjectWeak);
    450             result = env->IsSameObject(obj, me);
    451             env->DeleteLocalRef(me);
    452         }
    453         return result;
    454     }
    455 
    456     void warnIfStillLive() {
    457         if (mObject != NULL) {
    458             // Okay, something is wrong -- we have a hard reference to a live death
    459             // recipient on the VM side, but the list is being torn down.
    460             JNIEnv* env = javavm_to_jnienv(mVM);
    461             ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
    462             ScopedLocalRef<jstring> nameRef(env,
    463                     (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
    464             ScopedUtfChars nameUtf(env, nameRef.get());
    465             if (nameUtf.c_str() != NULL) {
    466                 LOGW("BinderProxy is being destroyed but the application did not call "
    467                         "unlinkToDeath to unlink all of its death recipients beforehand.  "
    468                         "Releasing leaked death recipient: %s", nameUtf.c_str());
    469             } else {
    470                 LOGW("BinderProxy being destroyed; unable to get DR object name");
    471                 env->ExceptionClear();
    472             }
    473         }
    474     }
    475 
    476 protected:
    477     virtual ~JavaDeathRecipient()
    478     {
    479         //LOGI("Removing death ref: recipient=%p\n", mObject);
    480         android_atomic_dec(&gNumDeathRefs);
    481         JNIEnv* env = javavm_to_jnienv(mVM);
    482         if (mObject != NULL) {
    483             env->DeleteGlobalRef(mObject);
    484         } else {
    485             env->DeleteWeakGlobalRef(mObjectWeak);
    486         }
    487     }
    488 
    489 private:
    490     JavaVM* const mVM;
    491     jobject mObject;
    492     jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
    493     wp<DeathRecipientList> mList;
    494 };
    495 
    496 // ----------------------------------------------------------------------------
    497 
    498 DeathRecipientList::DeathRecipientList() {
    499     LOGDEATH("New DRL @ %p", this);
    500 }
    501 
    502 DeathRecipientList::~DeathRecipientList() {
    503     LOGDEATH("Destroy DRL @ %p", this);
    504     AutoMutex _l(mLock);
    505 
    506     // Should never happen -- the JavaDeathRecipient objects that have added themselves
    507     // to the list are holding references on the list object.  Only when they are torn
    508     // down can the list header be destroyed.
    509     if (mList.size() > 0) {
    510         List< sp<JavaDeathRecipient> >::iterator iter;
    511         for (iter = mList.begin(); iter != mList.end(); iter++) {
    512             (*iter)->warnIfStillLive();
    513         }
    514     }
    515 }
    516 
    517 void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
    518     AutoMutex _l(mLock);
    519 
    520     LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
    521     mList.push_back(recipient);
    522 }
    523 
    524 void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
    525     AutoMutex _l(mLock);
    526 
    527     List< sp<JavaDeathRecipient> >::iterator iter;
    528     for (iter = mList.begin(); iter != mList.end(); iter++) {
    529         if (*iter == recipient) {
    530             LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
    531             mList.erase(iter);
    532             return;
    533         }
    534     }
    535 }
    536 
    537 sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
    538     AutoMutex _l(mLock);
    539 
    540     List< sp<JavaDeathRecipient> >::iterator iter;
    541     for (iter = mList.begin(); iter != mList.end(); iter++) {
    542         if ((*iter)->matches(recipient)) {
    543             return *iter;
    544         }
    545     }
    546     return NULL;
    547 }
    548 
    549 // ----------------------------------------------------------------------------
    550 
    551 namespace android {
    552 
    553 static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
    554 {
    555     android_atomic_dec(&gNumProxyRefs);
    556     JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
    557     env->DeleteGlobalRef((jobject)obj);
    558 }
    559 
    560 static Mutex mProxyLock;
    561 
    562 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
    563 {
    564     if (val == NULL) return NULL;
    565 
    566     if (val->checkSubclass(&gBinderOffsets)) {
    567         // One of our own!
    568         jobject object = static_cast<JavaBBinder*>(val.get())->object();
    569         LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
    570         return object;
    571     }
    572 
    573     // For the rest of the function we will hold this lock, to serialize
    574     // looking/creation of Java proxies for native Binder proxies.
    575     AutoMutex _l(mProxyLock);
    576 
    577     // Someone else's...  do we know about it?
    578     jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    579     if (object != NULL) {
    580         jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
    581         if (res != NULL) {
    582             LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
    583             return res;
    584         }
    585         LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
    586         android_atomic_dec(&gNumProxyRefs);
    587         val->detachObject(&gBinderProxyOffsets);
    588         env->DeleteGlobalRef(object);
    589     }
    590 
    591     object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    592     if (object != NULL) {
    593         LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
    594         // The proxy holds a reference to the native object.
    595         env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
    596         val->incStrong(object);
    597 
    598         // The native object needs to hold a weak reference back to the
    599         // proxy, so we can retrieve the same proxy if it is still active.
    600         jobject refObject = env->NewGlobalRef(
    601                 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
    602         val->attachObject(&gBinderProxyOffsets, refObject,
    603                 jnienv_to_javavm(env), proxy_cleanup);
    604 
    605         // Also remember the death recipients registered on this proxy
    606         sp<DeathRecipientList> drl = new DeathRecipientList;
    607         drl->incStrong((void*)javaObjectForIBinder);
    608         env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
    609 
    610         // Note that a new object reference has been created.
    611         android_atomic_inc(&gNumProxyRefs);
    612         incRefsCreated(env);
    613     }
    614 
    615     return object;
    616 }
    617 
    618 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
    619 {
    620     if (obj == NULL) return NULL;
    621 
    622     if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
    623         JavaBBinderHolder* jbh = (JavaBBinderHolder*)
    624             env->GetIntField(obj, gBinderOffsets.mObject);
    625         return jbh != NULL ? jbh->get(env, obj) : NULL;
    626     }
    627 
    628     if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
    629         return (IBinder*)
    630             env->GetIntField(obj, gBinderProxyOffsets.mObject);
    631     }
    632 
    633     LOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    634     return NULL;
    635 }
    636 
    637 Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
    638 {
    639     if (obj) {
    640         Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject);
    641         if (p != NULL) {
    642             return p;
    643         }
    644         jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
    645     }
    646     return NULL;
    647 }
    648 
    649 jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
    650 {
    651     return env->NewObject(
    652             gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
    653 }
    654 
    655 static void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
    656         bool canThrowRemoteException = false)
    657 {
    658     switch (err) {
    659         case UNKNOWN_ERROR:
    660             jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
    661             break;
    662         case NO_MEMORY:
    663             jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
    664             break;
    665         case INVALID_OPERATION:
    666             jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
    667             break;
    668         case BAD_VALUE:
    669             jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    670             break;
    671         case BAD_INDEX:
    672             jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
    673             break;
    674         case BAD_TYPE:
    675             jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    676             break;
    677         case NAME_NOT_FOUND:
    678             jniThrowException(env, "java/util/NoSuchElementException", NULL);
    679             break;
    680         case PERMISSION_DENIED:
    681             jniThrowException(env, "java/lang/SecurityException", NULL);
    682             break;
    683         case NOT_ENOUGH_DATA:
    684             jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
    685             break;
    686         case NO_INIT:
    687             jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
    688             break;
    689         case ALREADY_EXISTS:
    690             jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
    691             break;
    692         case DEAD_OBJECT:
    693             // DeadObjectException is a checked exception, only throw from certain methods.
    694             jniThrowException(env, canThrowRemoteException
    695                     ? "android/os/DeadObjectException"
    696                             : "java/lang/RuntimeException", NULL);
    697             break;
    698         case UNKNOWN_TRANSACTION:
    699             jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
    700             break;
    701         case FAILED_TRANSACTION:
    702             LOGE("!!! FAILED BINDER TRANSACTION !!!");
    703             // TransactionTooLargeException is a checked exception, only throw from certain methods.
    704             // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
    705             //        but it is not the only one.  The Binder driver can return BR_FAILED_REPLY
    706             //        for other reasons also, such as if the transaction is malformed or
    707             //        refers to an FD that has been closed.  We should change the driver
    708             //        to enable us to distinguish these cases in the future.
    709             jniThrowException(env, canThrowRemoteException
    710                     ? "android/os/TransactionTooLargeException"
    711                             : "java/lang/RuntimeException", NULL);
    712             break;
    713         case FDS_NOT_ALLOWED:
    714             jniThrowException(env, "java/lang/RuntimeException",
    715                     "Not allowed to write file descriptors here");
    716             break;
    717         default:
    718             LOGE("Unknown binder error code. 0x%x", err);
    719             String8 msg;
    720             msg.appendFormat("Unknown binder error code. 0x%x", err);
    721             // RemoteException is a checked exception, only throw from certain methods.
    722             jniThrowException(env, canThrowRemoteException
    723                     ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
    724             break;
    725     }
    726 }
    727 
    728 }
    729 
    730 // ----------------------------------------------------------------------------
    731 
    732 static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
    733 {
    734     return IPCThreadState::self()->getCallingPid();
    735 }
    736 
    737 static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
    738 {
    739     return IPCThreadState::self()->getCallingUid();
    740 }
    741 
    742 static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
    743 {
    744     return IPCThreadState::self()->clearCallingIdentity();
    745 }
    746 
    747 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
    748 {
    749     // XXX temporary sanity check to debug crashes.
    750     int uid = (int)(token>>32);
    751     if (uid > 0 && uid < 999) {
    752         // In Android currently there are no uids in this range.
    753         char buf[128];
    754         sprintf(buf, "Restoring bad calling ident: 0x%Lx", token);
    755         jniThrowException(env, "java/lang/IllegalStateException", buf);
    756         return;
    757     }
    758     IPCThreadState::self()->restoreCallingIdentity(token);
    759 }
    760 
    761 static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
    762 {
    763     IPCThreadState::self()->setStrictModePolicy(policyMask);
    764 }
    765 
    766 static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
    767 {
    768     return IPCThreadState::self()->getStrictModePolicy();
    769 }
    770 
    771 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
    772 {
    773     IPCThreadState::self()->flushCommands();
    774 }
    775 
    776 static void android_os_Binder_init(JNIEnv* env, jobject obj)
    777 {
    778     JavaBBinderHolder* jbh = new JavaBBinderHolder();
    779     if (jbh == NULL) {
    780         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
    781         return;
    782     }
    783     LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
    784     jbh->incStrong((void*)android_os_Binder_init);
    785     env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
    786 }
    787 
    788 static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
    789 {
    790     JavaBBinderHolder* jbh = (JavaBBinderHolder*)
    791         env->GetIntField(obj, gBinderOffsets.mObject);
    792     if (jbh != NULL) {
    793         env->SetIntField(obj, gBinderOffsets.mObject, 0);
    794         LOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
    795         jbh->decStrong((void*)android_os_Binder_init);
    796     } else {
    797         // Encountering an uninitialized binder is harmless.  All it means is that
    798         // the Binder was only partially initialized when its finalizer ran and called
    799         // destroy().  The Binder could be partially initialized for several reasons.
    800         // For example, a Binder subclass constructor might have thrown an exception before
    801         // it could delegate to its superclass's constructor.  Consequently init() would
    802         // not have been called and the holder pointer would remain NULL.
    803         LOGV("Java Binder %p: ignoring uninitialized binder", obj);
    804     }
    805 }
    806 
    807 // ----------------------------------------------------------------------------
    808 
    809 static const JNINativeMethod gBinderMethods[] = {
    810      /* name, signature, funcPtr */
    811     { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
    812     { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
    813     { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
    814     { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    815     { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    816     { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
    817     { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
    818     { "init", "()V", (void*)android_os_Binder_init },
    819     { "destroy", "()V", (void*)android_os_Binder_destroy }
    820 };
    821 
    822 const char* const kBinderPathName = "android/os/Binder";
    823 
    824 static int int_register_android_os_Binder(JNIEnv* env)
    825 {
    826     jclass clazz;
    827 
    828     clazz = env->FindClass(kBinderPathName);
    829     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
    830 
    831     gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    832     gBinderOffsets.mExecTransact
    833         = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
    834     assert(gBinderOffsets.mExecTransact);
    835 
    836     gBinderOffsets.mObject
    837         = env->GetFieldID(clazz, "mObject", "I");
    838     assert(gBinderOffsets.mObject);
    839 
    840     return AndroidRuntime::registerNativeMethods(
    841         env, kBinderPathName,
    842         gBinderMethods, NELEM(gBinderMethods));
    843 }
    844 
    845 // ****************************************************************************
    846 // ****************************************************************************
    847 // ****************************************************************************
    848 
    849 namespace android {
    850 
    851 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
    852 {
    853     return gNumLocalRefs;
    854 }
    855 
    856 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
    857 {
    858     return gNumProxyRefs;
    859 }
    860 
    861 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
    862 {
    863     return gNumDeathRefs;
    864 }
    865 
    866 }
    867 
    868 // ****************************************************************************
    869 // ****************************************************************************
    870 // ****************************************************************************
    871 
    872 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
    873 {
    874     sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    875     return javaObjectForIBinder(env, b);
    876 }
    877 
    878 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
    879 {
    880     sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    881     android::IPCThreadState::self()->joinThreadPool();
    882 }
    883 
    884 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
    885         jobject clazz, jboolean disable)
    886 {
    887     IPCThreadState::disableBackgroundScheduling(disable ? true : false);
    888 }
    889 
    890 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
    891 {
    892     LOGV("Gc has executed, clearing binder ops");
    893     android_atomic_and(0, &gNumRefsCreated);
    894 }
    895 
    896 // ----------------------------------------------------------------------------
    897 
    898 static const JNINativeMethod gBinderInternalMethods[] = {
    899      /* name, signature, funcPtr */
    900     { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    901     { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    902     { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    903     { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
    904 };
    905 
    906 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
    907 
    908 static int int_register_android_os_BinderInternal(JNIEnv* env)
    909 {
    910     jclass clazz;
    911 
    912     clazz = env->FindClass(kBinderInternalPathName);
    913     LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
    914 
    915     gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    916     gBinderInternalOffsets.mForceGc
    917         = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
    918     assert(gBinderInternalOffsets.mForceGc);
    919 
    920     return AndroidRuntime::registerNativeMethods(
    921         env, kBinderInternalPathName,
    922         gBinderInternalMethods, NELEM(gBinderInternalMethods));
    923 }
    924 
    925 // ****************************************************************************
    926 // ****************************************************************************
    927 // ****************************************************************************
    928 
    929 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
    930 {
    931     IBinder* target = (IBinder*)
    932         env->GetIntField(obj, gBinderProxyOffsets.mObject);
    933     if (target == NULL) {
    934         return JNI_FALSE;
    935     }
    936     status_t err = target->pingBinder();
    937     return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
    938 }
    939 
    940 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
    941 {
    942     IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
    943     if (target != NULL) {
    944         const String16& desc = target->getInterfaceDescriptor();
    945         return env->NewString(desc.string(), desc.size());
    946     }
    947     jniThrowException(env, "java/lang/RuntimeException",
    948             "No binder found for object");
    949     return NULL;
    950 }
    951 
    952 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
    953 {
    954     IBinder* target = (IBinder*)
    955         env->GetIntField(obj, gBinderProxyOffsets.mObject);
    956     if (target == NULL) {
    957         return JNI_FALSE;
    958     }
    959     bool alive = target->isBinderAlive();
    960     return alive ? JNI_TRUE : JNI_FALSE;
    961 }
    962 
    963 static int getprocname(pid_t pid, char *buf, size_t len) {
    964     char filename[20];
    965     FILE *f;
    966 
    967     sprintf(filename, "/proc/%d/cmdline", pid);
    968     f = fopen(filename, "r");
    969     if (!f) { *buf = '\0'; return 1; }
    970     if (!fgets(buf, len, f)) { *buf = '\0'; return 2; }
    971     fclose(f);
    972     return 0;
    973 }
    974 
    975 static bool push_eventlog_string(char** pos, const char* end, const char* str) {
    976     jint len = strlen(str);
    977     int space_needed = 1 + sizeof(len) + len;
    978     if (end - *pos < space_needed) {
    979         LOGW("not enough space for string. remain=%d; needed=%d",
    980              (end - *pos), space_needed);
    981         return false;
    982     }
    983     **pos = EVENT_TYPE_STRING;
    984     (*pos)++;
    985     memcpy(*pos, &len, sizeof(len));
    986     *pos += sizeof(len);
    987     memcpy(*pos, str, len);
    988     *pos += len;
    989     return true;
    990 }
    991 
    992 static bool push_eventlog_int(char** pos, const char* end, jint val) {
    993     int space_needed = 1 + sizeof(val);
    994     if (end - *pos < space_needed) {
    995         LOGW("not enough space for int.  remain=%d; needed=%d",
    996              (end - *pos), space_needed);
    997         return false;
    998     }
    999     **pos = EVENT_TYPE_INT;
   1000     (*pos)++;
   1001     memcpy(*pos, &val, sizeof(val));
   1002     *pos += sizeof(val);
   1003     return true;
   1004 }
   1005 
   1006 // From frameworks/base/core/java/android/content/EventLogTags.logtags:
   1007 #define LOGTAG_BINDER_OPERATION 52004
   1008 
   1009 static void conditionally_log_binder_call(int64_t start_millis,
   1010                                           IBinder* target, jint code) {
   1011     int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
   1012 
   1013     int sample_percent;
   1014     if (duration_ms >= 500) {
   1015         sample_percent = 100;
   1016     } else {
   1017         sample_percent = 100 * duration_ms / 500;
   1018         if (sample_percent == 0) {
   1019             return;
   1020         }
   1021         if (sample_percent < (random() % 100 + 1)) {
   1022             return;
   1023         }
   1024     }
   1025 
   1026     char process_name[40];
   1027     getprocname(getpid(), process_name, sizeof(process_name));
   1028     String8 desc(target->getInterfaceDescriptor());
   1029 
   1030     char buf[LOGGER_ENTRY_MAX_PAYLOAD];
   1031     buf[0] = EVENT_TYPE_LIST;
   1032     buf[1] = 5;
   1033     char* pos = &buf[2];
   1034     char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1];  // leave room for final \n
   1035     if (!push_eventlog_string(&pos, end, desc.string())) return;
   1036     if (!push_eventlog_int(&pos, end, code)) return;
   1037     if (!push_eventlog_int(&pos, end, duration_ms)) return;
   1038     if (!push_eventlog_string(&pos, end, process_name)) return;
   1039     if (!push_eventlog_int(&pos, end, sample_percent)) return;
   1040     *(pos++) = '\n';   // conventional with EVENT_TYPE_LIST apparently.
   1041     android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
   1042 }
   1043 
   1044 // We only measure binder call durations to potentially log them if
   1045 // we're on the main thread.  Unfortunately sim-eng doesn't seem to
   1046 // have gettid, so we just ignore this and don't log if we can't
   1047 // get the thread id.
   1048 static bool should_time_binder_calls() {
   1049 #ifdef HAVE_GETTID
   1050   return (getpid() == androidGetTid());
   1051 #else
   1052 #warning no gettid(), so not logging Binder calls...
   1053   return false;
   1054 #endif
   1055 }
   1056 
   1057 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
   1058         jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
   1059 {
   1060     if (dataObj == NULL) {
   1061         jniThrowNullPointerException(env, NULL);
   1062         return JNI_FALSE;
   1063     }
   1064 
   1065     Parcel* data = parcelForJavaObject(env, dataObj);
   1066     if (data == NULL) {
   1067         return JNI_FALSE;
   1068     }
   1069     Parcel* reply = parcelForJavaObject(env, replyObj);
   1070     if (reply == NULL && replyObj != NULL) {
   1071         return JNI_FALSE;
   1072     }
   1073 
   1074     IBinder* target = (IBinder*)
   1075         env->GetIntField(obj, gBinderProxyOffsets.mObject);
   1076     if (target == NULL) {
   1077         jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
   1078         return JNI_FALSE;
   1079     }
   1080 
   1081     LOGV("Java code calling transact on %p in Java object %p with code %d\n",
   1082             target, obj, code);
   1083 
   1084     // Only log the binder call duration for things on the Java-level main thread.
   1085     // But if we don't
   1086     const bool time_binder_calls = should_time_binder_calls();
   1087 
   1088     int64_t start_millis;
   1089     if (time_binder_calls) {
   1090         start_millis = uptimeMillis();
   1091     }
   1092     //printf("Transact from Java code to %p sending: ", target); data->print();
   1093     status_t err = target->transact(code, *data, reply, flags);
   1094     //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
   1095     if (time_binder_calls) {
   1096         conditionally_log_binder_call(start_millis, target, code);
   1097     }
   1098 
   1099     if (err == NO_ERROR) {
   1100         return JNI_TRUE;
   1101     } else if (err == UNKNOWN_TRANSACTION) {
   1102         return JNI_FALSE;
   1103     }
   1104 
   1105     signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
   1106     return JNI_FALSE;
   1107 }
   1108 
   1109 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
   1110         jobject recipient, jint flags) // throws RemoteException
   1111 {
   1112     if (recipient == NULL) {
   1113         jniThrowNullPointerException(env, NULL);
   1114         return;
   1115     }
   1116 
   1117     IBinder* target = (IBinder*)
   1118         env->GetIntField(obj, gBinderProxyOffsets.mObject);
   1119     if (target == NULL) {
   1120         LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
   1121         assert(false);
   1122     }
   1123 
   1124     LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
   1125 
   1126     if (!target->localBinder()) {
   1127         DeathRecipientList* list = (DeathRecipientList*)
   1128                 env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
   1129         sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
   1130         status_t err = target->linkToDeath(jdr, NULL, flags);
   1131         if (err != NO_ERROR) {
   1132             // Failure adding the death recipient, so clear its reference
   1133             // now.
   1134             jdr->clearReference();
   1135             signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
   1136         }
   1137     }
   1138 }
   1139 
   1140 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
   1141                                                  jobject recipient, jint flags)
   1142 {
   1143     jboolean res = JNI_FALSE;
   1144     if (recipient == NULL) {
   1145         jniThrowNullPointerException(env, NULL);
   1146         return res;
   1147     }
   1148 
   1149     IBinder* target = (IBinder*)
   1150         env->GetIntField(obj, gBinderProxyOffsets.mObject);
   1151     if (target == NULL) {
   1152         LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
   1153         return JNI_FALSE;
   1154     }
   1155 
   1156     LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
   1157 
   1158     if (!target->localBinder()) {
   1159         status_t err = NAME_NOT_FOUND;
   1160 
   1161         // If we find the matching recipient, proceed to unlink using that
   1162         DeathRecipientList* list = (DeathRecipientList*)
   1163                 env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
   1164         sp<JavaDeathRecipient> origJDR = list->find(recipient);
   1165         LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
   1166         if (origJDR != NULL) {
   1167             wp<IBinder::DeathRecipient> dr;
   1168             err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
   1169             if (err == NO_ERROR && dr != NULL) {
   1170                 sp<IBinder::DeathRecipient> sdr = dr.promote();
   1171                 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
   1172                 if (jdr != NULL) {
   1173                     jdr->clearReference();
   1174                 }
   1175             }
   1176         }
   1177 
   1178         if (err == NO_ERROR || err == DEAD_OBJECT) {
   1179             res = JNI_TRUE;
   1180         } else {
   1181             jniThrowException(env, "java/util/NoSuchElementException",
   1182                               "Death link does not exist");
   1183         }
   1184     }
   1185 
   1186     return res;
   1187 }
   1188 
   1189 static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
   1190 {
   1191     IBinder* b = (IBinder*)
   1192             env->GetIntField(obj, gBinderProxyOffsets.mObject);
   1193     DeathRecipientList* drl = (DeathRecipientList*)
   1194             env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
   1195 
   1196     LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
   1197     env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
   1198     env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0);
   1199     drl->decStrong((void*)javaObjectForIBinder);
   1200     b->decStrong(obj);
   1201 
   1202     IPCThreadState::self()->flushCommands();
   1203 }
   1204 
   1205 // ----------------------------------------------------------------------------
   1206 
   1207 static const JNINativeMethod gBinderProxyMethods[] = {
   1208      /* name, signature, funcPtr */
   1209     {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
   1210     {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
   1211     {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
   1212     {"transact",            "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
   1213     {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
   1214     {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
   1215     {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
   1216 };
   1217 
   1218 const char* const kBinderProxyPathName = "android/os/BinderProxy";
   1219 
   1220 static int int_register_android_os_BinderProxy(JNIEnv* env)
   1221 {
   1222     jclass clazz;
   1223 
   1224     clazz = env->FindClass("java/lang/ref/WeakReference");
   1225     LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
   1226     gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
   1227     gWeakReferenceOffsets.mGet
   1228         = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
   1229     assert(gWeakReferenceOffsets.mGet);
   1230 
   1231     clazz = env->FindClass("java/lang/Error");
   1232     LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
   1233     gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
   1234 
   1235     clazz = env->FindClass(kBinderProxyPathName);
   1236     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
   1237 
   1238     gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
   1239     gBinderProxyOffsets.mConstructor
   1240         = env->GetMethodID(clazz, "<init>", "()V");
   1241     assert(gBinderProxyOffsets.mConstructor);
   1242     gBinderProxyOffsets.mSendDeathNotice
   1243         = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
   1244     assert(gBinderProxyOffsets.mSendDeathNotice);
   1245 
   1246     gBinderProxyOffsets.mObject
   1247         = env->GetFieldID(clazz, "mObject", "I");
   1248     assert(gBinderProxyOffsets.mObject);
   1249     gBinderProxyOffsets.mSelf
   1250         = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
   1251     assert(gBinderProxyOffsets.mSelf);
   1252     gBinderProxyOffsets.mOrgue
   1253         = env->GetFieldID(clazz, "mOrgue", "I");
   1254     assert(gBinderProxyOffsets.mOrgue);
   1255 
   1256     clazz = env->FindClass("java/lang/Class");
   1257     LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class");
   1258     gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");
   1259     assert(gClassOffsets.mGetName);
   1260 
   1261     return AndroidRuntime::registerNativeMethods(
   1262         env, kBinderProxyPathName,
   1263         gBinderProxyMethods, NELEM(gBinderProxyMethods));
   1264 }
   1265 
   1266 // ****************************************************************************
   1267 // ****************************************************************************
   1268 // ****************************************************************************
   1269 
   1270 static jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz)
   1271 {
   1272     Parcel* parcel = parcelForJavaObject(env, clazz);
   1273     return parcel ? parcel->dataSize() : 0;
   1274 }
   1275 
   1276 static jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz)
   1277 {
   1278     Parcel* parcel = parcelForJavaObject(env, clazz);
   1279     return parcel ? parcel->dataAvail() : 0;
   1280 }
   1281 
   1282 static jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz)
   1283 {
   1284     Parcel* parcel = parcelForJavaObject(env, clazz);
   1285     return parcel ? parcel->dataPosition() : 0;
   1286 }
   1287 
   1288 static jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz)
   1289 {
   1290     Parcel* parcel = parcelForJavaObject(env, clazz);
   1291     return parcel ? parcel->dataCapacity() : 0;
   1292 }
   1293 
   1294 static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
   1295 {
   1296     Parcel* parcel = parcelForJavaObject(env, clazz);
   1297     if (parcel != NULL) {
   1298         const status_t err = parcel->setDataSize(size);
   1299         if (err != NO_ERROR) {
   1300             signalExceptionForError(env, clazz, err);
   1301         }
   1302     }
   1303 }
   1304 
   1305 static void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos)
   1306 {
   1307     Parcel* parcel = parcelForJavaObject(env, clazz);
   1308     if (parcel != NULL) {
   1309         parcel->setDataPosition(pos);
   1310     }
   1311 }
   1312 
   1313 static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size)
   1314 {
   1315     Parcel* parcel = parcelForJavaObject(env, clazz);
   1316     if (parcel != NULL) {
   1317         const status_t err = parcel->setDataCapacity(size);
   1318         if (err != NO_ERROR) {
   1319             signalExceptionForError(env, clazz, err);
   1320         }
   1321     }
   1322 }
   1323 
   1324 static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
   1325 {
   1326     Parcel* parcel = parcelForJavaObject(env, clazz);
   1327     jboolean ret = JNI_TRUE;
   1328     if (parcel != NULL) {
   1329         ret = (jboolean)parcel->pushAllowFds(allowFds);
   1330     }
   1331     return ret;
   1332 }
   1333 
   1334 static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
   1335 {
   1336     Parcel* parcel = parcelForJavaObject(env, clazz);
   1337     if (parcel != NULL) {
   1338         parcel->restoreAllowFds((bool)lastValue);
   1339     }
   1340 }
   1341 
   1342 static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
   1343                                           jobject data, jint offset,
   1344                                           jint length)
   1345 {
   1346     Parcel* parcel = parcelForJavaObject(env, clazz);
   1347     if (parcel == NULL) {
   1348         return;
   1349     }
   1350 
   1351     const status_t err = parcel->writeInt32(length);
   1352     if (err != NO_ERROR) {
   1353         signalExceptionForError(env, clazz, err);
   1354         return;
   1355     }
   1356 
   1357     void* dest = parcel->writeInplace(length);
   1358     if (dest == NULL) {
   1359         signalExceptionForError(env, clazz, NO_MEMORY);
   1360         return;
   1361     }
   1362 
   1363     jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
   1364     if (ar) {
   1365         memcpy(dest, ar + offset, length);
   1366         env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
   1367     }
   1368 }
   1369 
   1370 
   1371 static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
   1372 {
   1373     Parcel* parcel = parcelForJavaObject(env, clazz);
   1374     if (parcel != NULL) {
   1375         const status_t err = parcel->writeInt32(val);
   1376         if (err != NO_ERROR) {
   1377             signalExceptionForError(env, clazz, err);
   1378         }
   1379     }
   1380 }
   1381 
   1382 static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
   1383 {
   1384     Parcel* parcel = parcelForJavaObject(env, clazz);
   1385     if (parcel != NULL) {
   1386         const status_t err = parcel->writeInt64(val);
   1387         if (err != NO_ERROR) {
   1388             signalExceptionForError(env, clazz, err);
   1389         }
   1390     }
   1391 }
   1392 
   1393 static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
   1394 {
   1395     Parcel* parcel = parcelForJavaObject(env, clazz);
   1396     if (parcel != NULL) {
   1397         const status_t err = parcel->writeFloat(val);
   1398         if (err != NO_ERROR) {
   1399             signalExceptionForError(env, clazz, err);
   1400         }
   1401     }
   1402 }
   1403 
   1404 static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val)
   1405 {
   1406     Parcel* parcel = parcelForJavaObject(env, clazz);
   1407     if (parcel != NULL) {
   1408         const status_t err = parcel->writeDouble(val);
   1409         if (err != NO_ERROR) {
   1410             signalExceptionForError(env, clazz, err);
   1411         }
   1412     }
   1413 }
   1414 
   1415 static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
   1416 {
   1417     Parcel* parcel = parcelForJavaObject(env, clazz);
   1418     if (parcel != NULL) {
   1419         status_t err = NO_MEMORY;
   1420         if (val) {
   1421             const jchar* str = env->GetStringCritical(val, 0);
   1422             if (str) {
   1423                 err = parcel->writeString16(str, env->GetStringLength(val));
   1424                 env->ReleaseStringCritical(val, str);
   1425             }
   1426         } else {
   1427             err = parcel->writeString16(NULL, 0);
   1428         }
   1429         if (err != NO_ERROR) {
   1430             signalExceptionForError(env, clazz, err);
   1431         }
   1432     }
   1433 }
   1434 
   1435 static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
   1436 {
   1437     Parcel* parcel = parcelForJavaObject(env, clazz);
   1438     if (parcel != NULL) {
   1439         const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
   1440         if (err != NO_ERROR) {
   1441             signalExceptionForError(env, clazz, err);
   1442         }
   1443     }
   1444 }
   1445 
   1446 static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
   1447 {
   1448     Parcel* parcel = parcelForJavaObject(env, clazz);
   1449     if (parcel != NULL) {
   1450         const status_t err =
   1451                 parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
   1452         if (err != NO_ERROR) {
   1453             signalExceptionForError(env, clazz, err);
   1454         }
   1455     }
   1456 }
   1457 
   1458 static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
   1459 {
   1460     jbyteArray ret = NULL;
   1461 
   1462     Parcel* parcel = parcelForJavaObject(env, clazz);
   1463     if (parcel != NULL) {
   1464         int32_t len = parcel->readInt32();
   1465 
   1466         // sanity check the stored length against the true data size
   1467         if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
   1468             ret = env->NewByteArray(len);
   1469 
   1470             if (ret != NULL) {
   1471                 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
   1472                 if (a2) {
   1473                     const void* data = parcel->readInplace(len);
   1474                     memcpy(a2, data, len);
   1475                     env->ReleasePrimitiveArrayCritical(ret, a2, 0);
   1476                 }
   1477             }
   1478         }
   1479     }
   1480 
   1481     return ret;
   1482 }
   1483 
   1484 static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
   1485 {
   1486     Parcel* parcel = parcelForJavaObject(env, clazz);
   1487     if (parcel != NULL) {
   1488         return parcel->readInt32();
   1489     }
   1490     return 0;
   1491 }
   1492 
   1493 static jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz)
   1494 {
   1495     Parcel* parcel = parcelForJavaObject(env, clazz);
   1496     if (parcel != NULL) {
   1497         return parcel->readInt64();
   1498     }
   1499     return 0;
   1500 }
   1501 
   1502 static jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz)
   1503 {
   1504     Parcel* parcel = parcelForJavaObject(env, clazz);
   1505     if (parcel != NULL) {
   1506         return parcel->readFloat();
   1507     }
   1508     return 0;
   1509 }
   1510 
   1511 static jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz)
   1512 {
   1513     Parcel* parcel = parcelForJavaObject(env, clazz);
   1514     if (parcel != NULL) {
   1515         return parcel->readDouble();
   1516     }
   1517     return 0;
   1518 }
   1519 
   1520 static jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
   1521 {
   1522     Parcel* parcel = parcelForJavaObject(env, clazz);
   1523     if (parcel != NULL) {
   1524         size_t len;
   1525         const char16_t* str = parcel->readString16Inplace(&len);
   1526         if (str) {
   1527             return env->NewString(str, len);
   1528         }
   1529         return NULL;
   1530     }
   1531     return NULL;
   1532 }
   1533 
   1534 static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
   1535 {
   1536     Parcel* parcel = parcelForJavaObject(env, clazz);
   1537     if (parcel != NULL) {
   1538         return javaObjectForIBinder(env, parcel->readStrongBinder());
   1539     }
   1540     return NULL;
   1541 }
   1542 
   1543 static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
   1544 {
   1545     Parcel* parcel = parcelForJavaObject(env, clazz);
   1546     if (parcel != NULL) {
   1547         int fd = parcel->readFileDescriptor();
   1548         if (fd < 0) return NULL;
   1549         fd = dup(fd);
   1550         if (fd < 0) return NULL;
   1551         return jniCreateFileDescriptor(env, fd);
   1552     }
   1553     return NULL;
   1554 }
   1555 
   1556 static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
   1557                                                     jstring name, jint mode)
   1558 {
   1559     if (name == NULL) {
   1560         jniThrowNullPointerException(env, NULL);
   1561         return NULL;
   1562     }
   1563     const jchar* str = env->GetStringCritical(name, 0);
   1564     if (str == NULL) {
   1565         // Whatever, whatever.
   1566         jniThrowException(env, "java/lang/IllegalStateException", NULL);
   1567         return NULL;
   1568     }
   1569     String8 name8(str, env->GetStringLength(name));
   1570     env->ReleaseStringCritical(name, str);
   1571     int flags=0;
   1572     switch (mode&0x30000000) {
   1573         case 0:
   1574         case 0x10000000:
   1575             flags = O_RDONLY;
   1576             break;
   1577         case 0x20000000:
   1578             flags = O_WRONLY;
   1579             break;
   1580         case 0x30000000:
   1581             flags = O_RDWR;
   1582             break;
   1583     }
   1584 
   1585     if (mode&0x08000000) flags |= O_CREAT;
   1586     if (mode&0x04000000) flags |= O_TRUNC;
   1587     if (mode&0x02000000) flags |= O_APPEND;
   1588 
   1589     int realMode = S_IRWXU|S_IRWXG;
   1590     if (mode&0x00000001) realMode |= S_IROTH;
   1591     if (mode&0x00000002) realMode |= S_IWOTH;
   1592 
   1593     int fd = open(name8.string(), flags, realMode);
   1594     if (fd < 0) {
   1595         jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
   1596         return NULL;
   1597     }
   1598     jobject object = jniCreateFileDescriptor(env, fd);
   1599     if (object == NULL) {
   1600         close(fd);
   1601     }
   1602     return object;
   1603 }
   1604 
   1605 static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig)
   1606 {
   1607     if (orig == NULL) {
   1608         jniThrowNullPointerException(env, NULL);
   1609         return NULL;
   1610     }
   1611     int origfd = jniGetFDFromFileDescriptor(env, orig);
   1612     if (origfd < 0) {
   1613         jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
   1614         return NULL;
   1615     }
   1616 
   1617     int fd = dup(origfd);
   1618     if (fd < 0) {
   1619         jniThrowIOException(env, errno);
   1620         return NULL;
   1621     }
   1622     jobject object = jniCreateFileDescriptor(env, fd);
   1623     if (object == NULL) {
   1624         close(fd);
   1625     }
   1626     return object;
   1627 }
   1628 
   1629 static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
   1630 {
   1631     if (object == NULL) {
   1632         jniThrowNullPointerException(env, NULL);
   1633         return;
   1634     }
   1635     int fd = jniGetFDFromFileDescriptor(env, object);
   1636     if (fd >= 0) {
   1637         jniSetFileDescriptorOfFD(env, object, -1);
   1638         //LOGI("Closing ParcelFileDescriptor %d\n", fd);
   1639         close(fd);
   1640     }
   1641 }
   1642 
   1643 static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
   1644 {
   1645     if (object == NULL) {
   1646         jniThrowNullPointerException(env, NULL);
   1647         return;
   1648     }
   1649     int fd = jniGetFDFromFileDescriptor(env, object);
   1650     if (fd >= 0) {
   1651         jniSetFileDescriptorOfFD(env, object, -1);
   1652     }
   1653 }
   1654 
   1655 static void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz)
   1656 {
   1657     int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
   1658     if (own) {
   1659         Parcel* parcel = parcelForJavaObject(env, clazz);
   1660         if (parcel != NULL) {
   1661             //LOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel);
   1662             parcel->freeData();
   1663         }
   1664     }
   1665 }
   1666 
   1667 static void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
   1668 {
   1669     Parcel* parcel = (Parcel*)parcelInt;
   1670     int own = 0;
   1671     if (!parcel) {
   1672         //LOGI("Initializing obj %p: creating new Parcel\n", clazz);
   1673         own = 1;
   1674         parcel = new Parcel;
   1675     } else {
   1676         //LOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
   1677     }
   1678     if (parcel == NULL) {
   1679         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
   1680         return;
   1681     }
   1682     //LOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
   1683     env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
   1684     env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
   1685 }
   1686 
   1687 static void android_os_Parcel_destroy(JNIEnv* env, jobject clazz)
   1688 {
   1689     int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
   1690     if (own) {
   1691         Parcel* parcel = parcelForJavaObject(env, clazz);
   1692         env->SetIntField(clazz, gParcelOffsets.mObject, 0);
   1693         //LOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel);
   1694         delete parcel;
   1695     } else {
   1696         env->SetIntField(clazz, gParcelOffsets.mObject, 0);
   1697         //LOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz);
   1698     }
   1699 }
   1700 
   1701 static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
   1702 {
   1703     Parcel* parcel = parcelForJavaObject(env, clazz);
   1704     if (parcel == NULL) {
   1705        return NULL;
   1706     }
   1707 
   1708     // do not marshall if there are binder objects in the parcel
   1709     if (parcel->objectsCount())
   1710     {
   1711         jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
   1712         return NULL;
   1713     }
   1714 
   1715     jbyteArray ret = env->NewByteArray(parcel->dataSize());
   1716 
   1717     if (ret != NULL)
   1718     {
   1719         jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
   1720         if (array != NULL)
   1721         {
   1722             memcpy(array, parcel->data(), parcel->dataSize());
   1723             env->ReleasePrimitiveArrayCritical(ret, array, 0);
   1724         }
   1725     }
   1726 
   1727     return ret;
   1728 }
   1729 
   1730 static void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length)
   1731 {
   1732     Parcel* parcel = parcelForJavaObject(env, clazz);
   1733     if (parcel == NULL || length < 0) {
   1734        return;
   1735     }
   1736 
   1737     jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
   1738     if (array)
   1739     {
   1740         parcel->setDataSize(length);
   1741         parcel->setDataPosition(0);
   1742 
   1743         void* raw = parcel->writeInplace(length);
   1744         memcpy(raw, (array + offset), length);
   1745 
   1746         env->ReleasePrimitiveArrayCritical(data, array, 0);
   1747     }
   1748 }
   1749 
   1750 static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length)
   1751 {
   1752     Parcel* thisParcel = parcelForJavaObject(env, clazz);
   1753     if (thisParcel == NULL) {
   1754        return;
   1755     }
   1756     Parcel* otherParcel = parcelForJavaObject(env, parcel);
   1757     if (otherParcel == NULL) {
   1758        return;
   1759     }
   1760 
   1761     status_t err = thisParcel->appendFrom(otherParcel, offset, length);
   1762     if (err != NO_ERROR) {
   1763         signalExceptionForError(env, clazz, err);
   1764     }
   1765 }
   1766 
   1767 static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
   1768 {
   1769     jboolean ret = JNI_FALSE;
   1770     Parcel* parcel = parcelForJavaObject(env, clazz);
   1771     if (parcel != NULL) {
   1772         if (parcel->hasFileDescriptors()) {
   1773             ret = JNI_TRUE;
   1774         }
   1775     }
   1776     return ret;
   1777 }
   1778 
   1779 static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
   1780 {
   1781     Parcel* parcel = parcelForJavaObject(env, clazz);
   1782     if (parcel != NULL) {
   1783         // In the current implementation, the token is just the serialized interface name that
   1784         // the caller expects to be invoking
   1785         const jchar* str = env->GetStringCritical(name, 0);
   1786         if (str != NULL) {
   1787             parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
   1788             env->ReleaseStringCritical(name, str);
   1789         }
   1790     }
   1791 }
   1792 
   1793 static void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name)
   1794 {
   1795     jboolean ret = JNI_FALSE;
   1796 
   1797     Parcel* parcel = parcelForJavaObject(env, clazz);
   1798     if (parcel != NULL) {
   1799         const jchar* str = env->GetStringCritical(name, 0);
   1800         if (str) {
   1801             IPCThreadState* threadState = IPCThreadState::self();
   1802             const int32_t oldPolicy = threadState->getStrictModePolicy();
   1803             const bool isValid = parcel->enforceInterface(
   1804                 String16(str, env->GetStringLength(name)),
   1805                 threadState);
   1806             env->ReleaseStringCritical(name, str);
   1807             if (isValid) {
   1808                 const int32_t newPolicy = threadState->getStrictModePolicy();
   1809                 if (oldPolicy != newPolicy) {
   1810                     // Need to keep the Java-level thread-local strict
   1811                     // mode policy in sync for the libcore
   1812                     // enforcements, which involves an upcall back
   1813                     // into Java.  (We can't modify the
   1814                     // Parcel.enforceInterface signature, as it's
   1815                     // pseudo-public, and used via AIDL
   1816                     // auto-generation...)
   1817                     set_dalvik_blockguard_policy(env, newPolicy);
   1818                 }
   1819                 return;     // everything was correct -> return silently
   1820             }
   1821         }
   1822     }
   1823 
   1824     // all error conditions wind up here
   1825     jniThrowException(env, "java/lang/SecurityException",
   1826             "Binder invocation to an incorrect interface");
   1827 }
   1828 
   1829 // ----------------------------------------------------------------------------
   1830 
   1831 static const JNINativeMethod gParcelMethods[] = {
   1832     {"dataSize",            "()I", (void*)android_os_Parcel_dataSize},
   1833     {"dataAvail",           "()I", (void*)android_os_Parcel_dataAvail},
   1834     {"dataPosition",        "()I", (void*)android_os_Parcel_dataPosition},
   1835     {"dataCapacity",        "()I", (void*)android_os_Parcel_dataCapacity},
   1836     {"setDataSize",         "(I)V", (void*)android_os_Parcel_setDataSize},
   1837     {"setDataPosition",     "(I)V", (void*)android_os_Parcel_setDataPosition},
   1838     {"setDataCapacity",     "(I)V", (void*)android_os_Parcel_setDataCapacity},
   1839     {"pushAllowFds",        "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
   1840     {"restoreAllowFds",     "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
   1841     {"writeNative",         "([BII)V", (void*)android_os_Parcel_writeNative},
   1842     {"writeInt",            "(I)V", (void*)android_os_Parcel_writeInt},
   1843     {"writeLong",           "(J)V", (void*)android_os_Parcel_writeLong},
   1844     {"writeFloat",          "(F)V", (void*)android_os_Parcel_writeFloat},
   1845     {"writeDouble",         "(D)V", (void*)android_os_Parcel_writeDouble},
   1846     {"writeString",         "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString},
   1847     {"writeStrongBinder",   "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
   1848     {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
   1849     {"createByteArray",     "()[B", (void*)android_os_Parcel_createByteArray},
   1850     {"readInt",             "()I", (void*)android_os_Parcel_readInt},
   1851     {"readLong",            "()J", (void*)android_os_Parcel_readLong},
   1852     {"readFloat",           "()F", (void*)android_os_Parcel_readFloat},
   1853     {"readDouble",          "()D", (void*)android_os_Parcel_readDouble},
   1854     {"readString",          "()Ljava/lang/String;", (void*)android_os_Parcel_readString},
   1855     {"readStrongBinder",    "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
   1856     {"internalReadFileDescriptor",  "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
   1857     {"openFileDescriptor",  "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
   1858     {"dupFileDescriptor",   "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
   1859     {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
   1860     {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
   1861     {"freeBuffer",          "()V", (void*)android_os_Parcel_freeBuffer},
   1862     {"init",                "(I)V", (void*)android_os_Parcel_init},
   1863     {"destroy",             "()V", (void*)android_os_Parcel_destroy},
   1864     {"marshall",            "()[B", (void*)android_os_Parcel_marshall},
   1865     {"unmarshall",          "([BII)V", (void*)android_os_Parcel_unmarshall},
   1866     {"appendFrom",          "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom},
   1867     {"hasFileDescriptors",  "()Z", (void*)android_os_Parcel_hasFileDescriptors},
   1868     {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
   1869     {"enforceInterface",    "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
   1870 };
   1871 
   1872 const char* const kParcelPathName = "android/os/Parcel";
   1873 
   1874 static int int_register_android_os_Parcel(JNIEnv* env)
   1875 {
   1876     jclass clazz;
   1877 
   1878     clazz = env->FindClass("android/util/Log");
   1879     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log");
   1880     gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
   1881     gLogOffsets.mLogE = env->GetStaticMethodID(
   1882         clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
   1883     assert(gLogOffsets.mLogE);
   1884 
   1885     clazz = env->FindClass("android/os/ParcelFileDescriptor");
   1886     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
   1887     gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
   1888     gParcelFileDescriptorOffsets.mConstructor
   1889         = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
   1890 
   1891     clazz = env->FindClass(kParcelPathName);
   1892     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
   1893 
   1894     gParcelOffsets.mObject
   1895         = env->GetFieldID(clazz, "mObject", "I");
   1896     gParcelOffsets.mOwnObject
   1897         = env->GetFieldID(clazz, "mOwnObject", "I");
   1898 
   1899     clazz = env->FindClass("android/os/StrictMode");
   1900     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode");
   1901     gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
   1902     gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID(
   1903         clazz, "onBinderStrictModePolicyChange", "(I)V");
   1904     LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL,
   1905                  "Unable to find strict mode callback.");
   1906 
   1907     return AndroidRuntime::registerNativeMethods(
   1908         env, kParcelPathName,
   1909         gParcelMethods, NELEM(gParcelMethods));
   1910 }
   1911 
   1912 int register_android_os_Binder(JNIEnv* env)
   1913 {
   1914     if (int_register_android_os_Binder(env) < 0)
   1915         return -1;
   1916     if (int_register_android_os_BinderInternal(env) < 0)
   1917         return -1;
   1918     if (int_register_android_os_BinderProxy(env) < 0)
   1919         return -1;
   1920     if (int_register_android_os_Parcel(env) < 0)
   1921         return -1;
   1922     return 0;
   1923 }
   1924