Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2012 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 "Parcel"
     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 <binder/Parcel.h>
     39 #include <binder/ProcessState.h>
     40 #include <binder/IServiceManager.h>
     41 #include <utils/threads.h>
     42 #include <utils/String8.h>
     43 
     44 #include <ScopedUtfChars.h>
     45 #include <ScopedLocalRef.h>
     46 
     47 #include <android_runtime/AndroidRuntime.h>
     48 
     49 //#undef ALOGV
     50 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
     51 
     52 #define DEBUG_DEATH 0
     53 #if DEBUG_DEATH
     54 #define LOGDEATH ALOGD
     55 #else
     56 #define LOGDEATH ALOGV
     57 #endif
     58 
     59 namespace android {
     60 
     61 static struct parcel_offsets_t
     62 {
     63     jclass clazz;
     64     jfieldID mNativePtr;
     65     jmethodID obtain;
     66     jmethodID recycle;
     67 } gParcelOffsets;
     68 
     69 Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
     70 {
     71     if (obj) {
     72         Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
     73         if (p != NULL) {
     74             return p;
     75         }
     76         jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
     77     }
     78     return NULL;
     79 }
     80 
     81 jobject createJavaParcelObject(JNIEnv* env)
     82 {
     83     return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain);
     84 }
     85 
     86 void recycleJavaParcelObject(JNIEnv* env, jobject parcelObj)
     87 {
     88     env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
     89 }
     90 
     91 static jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jlong nativePtr)
     92 {
     93     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
     94     return parcel ? parcel->dataSize() : 0;
     95 }
     96 
     97 static jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jlong nativePtr)
     98 {
     99     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    100     return parcel ? parcel->dataAvail() : 0;
    101 }
    102 
    103 static jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jlong nativePtr)
    104 {
    105     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    106     return parcel ? parcel->dataPosition() : 0;
    107 }
    108 
    109 static jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr)
    110 {
    111     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    112     return parcel ? parcel->dataCapacity() : 0;
    113 }
    114 
    115 static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
    116 {
    117     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    118     if (parcel != NULL) {
    119         const status_t err = parcel->setDataSize(size);
    120         if (err != NO_ERROR) {
    121             signalExceptionForError(env, clazz, err);
    122         }
    123     }
    124 }
    125 
    126 static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jlong nativePtr, jint pos)
    127 {
    128     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    129     if (parcel != NULL) {
    130         parcel->setDataPosition(pos);
    131     }
    132 }
    133 
    134 static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
    135 {
    136     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    137     if (parcel != NULL) {
    138         const status_t err = parcel->setDataCapacity(size);
    139         if (err != NO_ERROR) {
    140             signalExceptionForError(env, clazz, err);
    141         }
    142     }
    143 }
    144 
    145 static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean allowFds)
    146 {
    147     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    148     jboolean ret = JNI_TRUE;
    149     if (parcel != NULL) {
    150         ret = (jboolean)parcel->pushAllowFds(allowFds);
    151     }
    152     return ret;
    153 }
    154 
    155 static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean lastValue)
    156 {
    157     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    158     if (parcel != NULL) {
    159         parcel->restoreAllowFds((bool)lastValue);
    160     }
    161 }
    162 
    163 static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
    164                                           jint offset, jint length)
    165 {
    166     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    167     if (parcel == NULL) {
    168         return;
    169     }
    170 
    171     const status_t err = parcel->writeInt32(length);
    172     if (err != NO_ERROR) {
    173         signalExceptionForError(env, clazz, err);
    174         return;
    175     }
    176 
    177     void* dest = parcel->writeInplace(length);
    178     if (dest == NULL) {
    179         signalExceptionForError(env, clazz, NO_MEMORY);
    180         return;
    181     }
    182 
    183     jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
    184     if (ar) {
    185         memcpy(dest, ar + offset, length);
    186         env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
    187     }
    188 }
    189 
    190 static void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
    191                                         jint offset, jint length) {
    192     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    193     if (parcel == NULL) {
    194         return;
    195     }
    196 
    197     if (data == NULL) {
    198         const status_t err = parcel->writeInt32(-1);
    199         if (err != NO_ERROR) {
    200             signalExceptionForError(env, clazz, err);
    201         }
    202         return;
    203     }
    204 
    205     const status_t err = parcel->writeInt32(length);
    206     if (err != NO_ERROR) {
    207         signalExceptionForError(env, clazz, err);
    208         return;
    209     }
    210 
    211     android::Parcel::WritableBlob blob;
    212     android::status_t err2 = parcel->writeBlob(length, &blob);
    213     if (err2 != NO_ERROR) {
    214         signalExceptionForError(env, clazz, err2);
    215         return;
    216     }
    217 
    218     jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
    219     if (ar == NULL) {
    220         memset(blob.data(), 0, length);
    221     } else {
    222         memcpy(blob.data(), ar + offset, length);
    223         env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
    224     }
    225 
    226     blob.release();
    227 }
    228 
    229 static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
    230     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    231     const status_t err = parcel->writeInt32(val);
    232     if (err != NO_ERROR) {
    233         signalExceptionForError(env, clazz, err);
    234     }
    235 }
    236 
    237 static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jlong nativePtr, jlong val)
    238 {
    239     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    240     if (parcel != NULL) {
    241         const status_t err = parcel->writeInt64(val);
    242         if (err != NO_ERROR) {
    243             signalExceptionForError(env, clazz, err);
    244         }
    245     }
    246 }
    247 
    248 static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jlong nativePtr, jfloat val)
    249 {
    250     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    251     if (parcel != NULL) {
    252         const status_t err = parcel->writeFloat(val);
    253         if (err != NO_ERROR) {
    254             signalExceptionForError(env, clazz, err);
    255         }
    256     }
    257 }
    258 
    259 static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativePtr, jdouble val)
    260 {
    261     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    262     if (parcel != NULL) {
    263         const status_t err = parcel->writeDouble(val);
    264         if (err != NO_ERROR) {
    265             signalExceptionForError(env, clazz, err);
    266         }
    267     }
    268 }
    269 
    270 static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
    271 {
    272     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    273     if (parcel != NULL) {
    274         status_t err = NO_MEMORY;
    275         if (val) {
    276             const jchar* str = env->GetStringCritical(val, 0);
    277             if (str) {
    278                 err = parcel->writeString16(str, env->GetStringLength(val));
    279                 env->ReleaseStringCritical(val, str);
    280             }
    281         } else {
    282             err = parcel->writeString16(NULL, 0);
    283         }
    284         if (err != NO_ERROR) {
    285             signalExceptionForError(env, clazz, err);
    286         }
    287     }
    288 }
    289 
    290 static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
    291 {
    292     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    293     if (parcel != NULL) {
    294         const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
    295         if (err != NO_ERROR) {
    296             signalExceptionForError(env, clazz, err);
    297         }
    298     }
    299 }
    300 
    301 static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
    302 {
    303     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    304     if (parcel != NULL) {
    305         const status_t err =
    306                 parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
    307         if (err != NO_ERROR) {
    308             signalExceptionForError(env, clazz, err);
    309         }
    310     }
    311 }
    312 
    313 static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr)
    314 {
    315     jbyteArray ret = NULL;
    316 
    317     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    318     if (parcel != NULL) {
    319         int32_t len = parcel->readInt32();
    320 
    321         // sanity check the stored length against the true data size
    322         if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
    323             ret = env->NewByteArray(len);
    324 
    325             if (ret != NULL) {
    326                 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
    327                 if (a2) {
    328                     const void* data = parcel->readInplace(len);
    329                     memcpy(a2, data, len);
    330                     env->ReleasePrimitiveArrayCritical(ret, a2, 0);
    331                 }
    332             }
    333         }
    334     }
    335 
    336     return ret;
    337 }
    338 
    339 static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
    340 {
    341     jbyteArray ret = NULL;
    342 
    343     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    344     if (parcel != NULL) {
    345         int32_t len = parcel->readInt32();
    346         if (len >= 0) {
    347             android::Parcel::ReadableBlob blob;
    348             android::status_t err = parcel->readBlob(len, &blob);
    349             if (err != NO_ERROR) {
    350                 signalExceptionForError(env, clazz, err);
    351                 return NULL;
    352             }
    353 
    354             ret = env->NewByteArray(len);
    355             if (ret != NULL) {
    356                 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
    357                 if (a2) {
    358                     memcpy(a2, blob.data(), len);
    359                     env->ReleasePrimitiveArrayCritical(ret, a2, 0);
    360                 }
    361             }
    362             blob.release();
    363         }
    364     }
    365 
    366     return ret;
    367 }
    368 
    369 static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jlong nativePtr)
    370 {
    371     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    372     if (parcel != NULL) {
    373         return parcel->readInt32();
    374     }
    375     return 0;
    376 }
    377 
    378 static jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jlong nativePtr)
    379 {
    380     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    381     if (parcel != NULL) {
    382         return parcel->readInt64();
    383     }
    384     return 0;
    385 }
    386 
    387 static jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jlong nativePtr)
    388 {
    389     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    390     if (parcel != NULL) {
    391         return parcel->readFloat();
    392     }
    393     return 0;
    394 }
    395 
    396 static jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jlong nativePtr)
    397 {
    398     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    399     if (parcel != NULL) {
    400         return parcel->readDouble();
    401     }
    402     return 0;
    403 }
    404 
    405 static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr)
    406 {
    407     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    408     if (parcel != NULL) {
    409         size_t len;
    410         const char16_t* str = parcel->readString16Inplace(&len);
    411         if (str) {
    412             return env->NewString(str, len);
    413         }
    414         return NULL;
    415     }
    416     return NULL;
    417 }
    418 
    419 static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
    420 {
    421     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    422     if (parcel != NULL) {
    423         return javaObjectForIBinder(env, parcel->readStrongBinder());
    424     }
    425     return NULL;
    426 }
    427 
    428 static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr)
    429 {
    430     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    431     if (parcel != NULL) {
    432         int fd = parcel->readFileDescriptor();
    433         if (fd < 0) return NULL;
    434         fd = dup(fd);
    435         if (fd < 0) return NULL;
    436         return jniCreateFileDescriptor(env, fd);
    437     }
    438     return NULL;
    439 }
    440 
    441 static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
    442                                                     jstring name, jint mode)
    443 {
    444     if (name == NULL) {
    445         jniThrowNullPointerException(env, NULL);
    446         return NULL;
    447     }
    448     const jchar* str = env->GetStringCritical(name, 0);
    449     if (str == NULL) {
    450         // Whatever, whatever.
    451         jniThrowException(env, "java/lang/IllegalStateException", NULL);
    452         return NULL;
    453     }
    454     String8 name8(str, env->GetStringLength(name));
    455     env->ReleaseStringCritical(name, str);
    456     int flags=0;
    457     switch (mode&0x30000000) {
    458         case 0:
    459         case 0x10000000:
    460             flags = O_RDONLY;
    461             break;
    462         case 0x20000000:
    463             flags = O_WRONLY;
    464             break;
    465         case 0x30000000:
    466             flags = O_RDWR;
    467             break;
    468     }
    469 
    470     if (mode&0x08000000) flags |= O_CREAT;
    471     if (mode&0x04000000) flags |= O_TRUNC;
    472     if (mode&0x02000000) flags |= O_APPEND;
    473 
    474     int realMode = S_IRWXU|S_IRWXG;
    475     if (mode&0x00000001) realMode |= S_IROTH;
    476     if (mode&0x00000002) realMode |= S_IWOTH;
    477 
    478     int fd = open(name8.string(), flags, realMode);
    479     if (fd < 0) {
    480         jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
    481         return NULL;
    482     }
    483     jobject object = jniCreateFileDescriptor(env, fd);
    484     if (object == NULL) {
    485         close(fd);
    486     }
    487     return object;
    488 }
    489 
    490 static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
    491 {
    492     if (orig == NULL) {
    493         jniThrowNullPointerException(env, NULL);
    494         return NULL;
    495     }
    496     int origfd = jniGetFDFromFileDescriptor(env, orig);
    497     if (origfd < 0) {
    498         jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
    499         return NULL;
    500     }
    501 
    502     int fd = dup(origfd);
    503     if (fd < 0) {
    504         jniThrowIOException(env, errno);
    505         return NULL;
    506     }
    507     jobject object = jniCreateFileDescriptor(env, fd);
    508     if (object == NULL) {
    509         close(fd);
    510     }
    511     return object;
    512 }
    513 
    514 static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
    515 {
    516     if (object == NULL) {
    517         jniThrowNullPointerException(env, NULL);
    518         return;
    519     }
    520     int fd = jniGetFDFromFileDescriptor(env, object);
    521     if (fd >= 0) {
    522         jniSetFileDescriptorOfFD(env, object, -1);
    523         //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
    524         close(fd);
    525     }
    526 }
    527 
    528 static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
    529 {
    530     if (object == NULL) {
    531         jniThrowNullPointerException(env, NULL);
    532         return;
    533     }
    534     int fd = jniGetFDFromFileDescriptor(env, object);
    535     if (fd >= 0) {
    536         jniSetFileDescriptorOfFD(env, object, -1);
    537     }
    538 }
    539 
    540 static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
    541 {
    542     Parcel* parcel = new Parcel();
    543     return reinterpret_cast<jlong>(parcel);
    544 }
    545 
    546 static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
    547 {
    548     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    549     if (parcel != NULL) {
    550         parcel->freeData();
    551     }
    552 }
    553 
    554 static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr)
    555 {
    556     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    557     delete parcel;
    558 }
    559 
    560 static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
    561 {
    562     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    563     if (parcel == NULL) {
    564        return NULL;
    565     }
    566 
    567     // do not marshall if there are binder objects in the parcel
    568     if (parcel->objectsCount())
    569     {
    570         jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
    571         return NULL;
    572     }
    573 
    574     jbyteArray ret = env->NewByteArray(parcel->dataSize());
    575 
    576     if (ret != NULL)
    577     {
    578         jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
    579         if (array != NULL)
    580         {
    581             memcpy(array, parcel->data(), parcel->dataSize());
    582             env->ReleasePrimitiveArrayCritical(ret, array, 0);
    583         }
    584     }
    585 
    586     return ret;
    587 }
    588 
    589 static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
    590                                          jbyteArray data, jint offset, jint length)
    591 {
    592     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    593     if (parcel == NULL || length < 0) {
    594        return;
    595     }
    596 
    597     jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
    598     if (array)
    599     {
    600         parcel->setDataSize(length);
    601         parcel->setDataPosition(0);
    602 
    603         void* raw = parcel->writeInplace(length);
    604         memcpy(raw, (array + offset), length);
    605 
    606         env->ReleasePrimitiveArrayCritical(data, array, 0);
    607     }
    608 }
    609 
    610 static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
    611                                          jlong otherNativePtr, jint offset, jint length)
    612 {
    613     Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
    614     if (thisParcel == NULL) {
    615        return;
    616     }
    617     Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
    618     if (otherParcel == NULL) {
    619        return;
    620     }
    621 
    622     status_t err = thisParcel->appendFrom(otherParcel, offset, length);
    623     if (err != NO_ERROR) {
    624         signalExceptionForError(env, clazz, err);
    625     }
    626 }
    627 
    628 static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jlong nativePtr)
    629 {
    630     jboolean ret = JNI_FALSE;
    631     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    632     if (parcel != NULL) {
    633         if (parcel->hasFileDescriptors()) {
    634             ret = JNI_TRUE;
    635         }
    636     }
    637     return ret;
    638 }
    639 
    640 static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr,
    641                                                   jstring name)
    642 {
    643     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    644     if (parcel != NULL) {
    645         // In the current implementation, the token is just the serialized interface name that
    646         // the caller expects to be invoking
    647         const jchar* str = env->GetStringCritical(name, 0);
    648         if (str != NULL) {
    649             parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
    650             env->ReleaseStringCritical(name, str);
    651         }
    652     }
    653 }
    654 
    655 static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
    656 {
    657     jboolean ret = JNI_FALSE;
    658 
    659     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    660     if (parcel != NULL) {
    661         const jchar* str = env->GetStringCritical(name, 0);
    662         if (str) {
    663             IPCThreadState* threadState = IPCThreadState::self();
    664             const int32_t oldPolicy = threadState->getStrictModePolicy();
    665             const bool isValid = parcel->enforceInterface(
    666                 String16(str, env->GetStringLength(name)),
    667                 threadState);
    668             env->ReleaseStringCritical(name, str);
    669             if (isValid) {
    670                 const int32_t newPolicy = threadState->getStrictModePolicy();
    671                 if (oldPolicy != newPolicy) {
    672                     // Need to keep the Java-level thread-local strict
    673                     // mode policy in sync for the libcore
    674                     // enforcements, which involves an upcall back
    675                     // into Java.  (We can't modify the
    676                     // Parcel.enforceInterface signature, as it's
    677                     // pseudo-public, and used via AIDL
    678                     // auto-generation...)
    679                     set_dalvik_blockguard_policy(env, newPolicy);
    680                 }
    681                 return;     // everything was correct -> return silently
    682             }
    683         }
    684     }
    685 
    686     // all error conditions wind up here
    687     jniThrowException(env, "java/lang/SecurityException",
    688             "Binder invocation to an incorrect interface");
    689 }
    690 
    691 static jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz)
    692 {
    693     return Parcel::getGlobalAllocSize();
    694 }
    695 
    696 static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz)
    697 {
    698     return Parcel::getGlobalAllocCount();
    699 }
    700 
    701 // ----------------------------------------------------------------------------
    702 
    703 static const JNINativeMethod gParcelMethods[] = {
    704     {"nativeDataSize",            "(J)I", (void*)android_os_Parcel_dataSize},
    705     {"nativeDataAvail",           "(J)I", (void*)android_os_Parcel_dataAvail},
    706     {"nativeDataPosition",        "(J)I", (void*)android_os_Parcel_dataPosition},
    707     {"nativeDataCapacity",        "(J)I", (void*)android_os_Parcel_dataCapacity},
    708     {"nativeSetDataSize",         "(JI)V", (void*)android_os_Parcel_setDataSize},
    709     {"nativeSetDataPosition",     "(JI)V", (void*)android_os_Parcel_setDataPosition},
    710     {"nativeSetDataCapacity",     "(JI)V", (void*)android_os_Parcel_setDataCapacity},
    711 
    712     {"nativePushAllowFds",        "(JZ)Z", (void*)android_os_Parcel_pushAllowFds},
    713     {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
    714 
    715     {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeNative},
    716     {"nativeWriteBlob",           "(J[BII)V", (void*)android_os_Parcel_writeBlob},
    717     {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
    718     {"nativeWriteLong",           "(JJ)V", (void*)android_os_Parcel_writeLong},
    719     {"nativeWriteFloat",          "(JF)V", (void*)android_os_Parcel_writeFloat},
    720     {"nativeWriteDouble",         "(JD)V", (void*)android_os_Parcel_writeDouble},
    721     {"nativeWriteString",         "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
    722     {"nativeWriteStrongBinder",   "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
    723     {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
    724 
    725     {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
    726     {"nativeReadBlob",            "(J)[B", (void*)android_os_Parcel_readBlob},
    727     {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},
    728     {"nativeReadLong",            "(J)J", (void*)android_os_Parcel_readLong},
    729     {"nativeReadFloat",           "(J)F", (void*)android_os_Parcel_readFloat},
    730     {"nativeReadDouble",          "(J)D", (void*)android_os_Parcel_readDouble},
    731     {"nativeReadString",          "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
    732     {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
    733     {"nativeReadFileDescriptor",  "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
    734 
    735     {"openFileDescriptor",        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
    736     {"dupFileDescriptor",         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
    737     {"closeFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
    738     {"clearFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
    739 
    740     {"nativeCreate",              "()J", (void*)android_os_Parcel_create},
    741     {"nativeFreeBuffer",          "(J)V", (void*)android_os_Parcel_freeBuffer},
    742     {"nativeDestroy",             "(J)V", (void*)android_os_Parcel_destroy},
    743 
    744     {"nativeMarshall",            "(J)[B", (void*)android_os_Parcel_marshall},
    745     {"nativeUnmarshall",          "(J[BII)V", (void*)android_os_Parcel_unmarshall},
    746     {"nativeAppendFrom",          "(JJII)V", (void*)android_os_Parcel_appendFrom},
    747     {"nativeHasFileDescriptors",  "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
    748     {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
    749     {"nativeEnforceInterface",    "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
    750 
    751     {"getGlobalAllocSize",        "()J", (void*)android_os_Parcel_getGlobalAllocSize},
    752     {"getGlobalAllocCount",       "()J", (void*)android_os_Parcel_getGlobalAllocCount},
    753 };
    754 
    755 const char* const kParcelPathName = "android/os/Parcel";
    756 
    757 int register_android_os_Parcel(JNIEnv* env)
    758 {
    759     jclass clazz;
    760 
    761     clazz = env->FindClass(kParcelPathName);
    762     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
    763 
    764     gParcelOffsets.clazz = (jclass) env->NewGlobalRef(clazz);
    765     gParcelOffsets.mNativePtr = env->GetFieldID(clazz, "mNativePtr", "J");
    766     gParcelOffsets.obtain = env->GetStaticMethodID(clazz, "obtain",
    767                                                    "()Landroid/os/Parcel;");
    768     gParcelOffsets.recycle = env->GetMethodID(clazz, "recycle", "()V");
    769 
    770     return AndroidRuntime::registerNativeMethods(
    771         env, kParcelPathName,
    772         gParcelMethods, NELEM(gParcelMethods));
    773 }
    774 
    775 };
    776