android_os_Parcel.cpp revision 8ab665dda40ab10e60fc69392022171f454af530
1873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat/*
2873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Copyright (C) 2012 The Android Open Source Project
3873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *
4873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * you may not use this file except in compliance with the License.
6873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * You may obtain a copy of the License at
7873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *
8873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *
10873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Unless required by applicable law or agreed to in writing, software
11873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * See the License for the specific language governing permissions and
14873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * limitations under the License.
15873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */
16873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
17873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#define LOG_TAG "Parcel"
18873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat//#define LOG_NDEBUG 0
19873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
20ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat#include "android_os_Parcel.h"
214d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include "android_util_Binder.h"
22b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti
239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey#include "JNIHelp.h"
2459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
256bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen#include <fcntl.h>
269ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff#include <stdio.h>
2777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn#include <sys/stat.h>
28ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat#include <sys/types.h>
29873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <unistd.h>
30873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
31873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <utils/Atomic.h>
32873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <binder/IInterface.h>
33873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <binder/IPCThreadState.h>
34873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <utils/Log.h>
35873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <utils/SystemClock.h>
36873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <utils/List.h>
37873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <utils/KeyedVector.h>
38873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#include <binder/Parcel.h>
394d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <binder/ProcessState.h>
404d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <binder/IServiceManager.h>
414d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <utils/threads.h>
424d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <utils/String8.h>
434d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
444d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <ScopedUtfChars.h>
454d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <ScopedLocalRef.h>
464d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
474d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat#include <android_runtime/AndroidRuntime.h>
484d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
49873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat//#undef ALOGV
50873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
51873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
52873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#define DEBUG_DEATH 0
53873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat#if DEBUG_DEATH
54ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat#define LOGDEATH ALOGD
55ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat#else
56ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat#define LOGDEATH ALOGV
57ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat#endif
58ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
59ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehatnamespace android {
60ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
61ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehatstatic struct parcel_offsets_t
62ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat{
63ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat    jclass clazz;
64ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat    jfieldID mNativePtr;
65f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff    jmethodID obtain;
66f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff    jmethodID recycle;
67f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff} gParcelOffsets;
68f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff
69f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan SheriffParcel* parcelForJavaObject(JNIEnv* env, jobject obj)
707244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff{
717244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff    if (obj) {
727244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff        Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
737244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff        if (p != NULL) {
747244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff            return p;
757244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff        }
767244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
777244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff    }
787244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff    return NULL;
797244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff}
807329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff
817329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriffjobject createJavaParcelObject(JNIEnv* env)
827329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff{
837329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff    return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain);
847329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff}
857960d9f888e31602e17b8856c77a3826bf8c841erepo sync
867960d9f888e31602e17b8856c77a3826bf8c841erepo syncvoid recycleJavaParcelObject(JNIEnv* env, jobject parcelObj)
877960d9f888e31602e17b8856c77a3826bf8c841erepo sync{
887960d9f888e31602e17b8856c77a3826bf8c841erepo sync    env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
897960d9f888e31602e17b8856c77a3826bf8c841erepo sync}
907960d9f888e31602e17b8856c77a3826bf8c841erepo sync
917960d9f888e31602e17b8856c77a3826bf8c841erepo syncstatic jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jlong nativePtr)
927960d9f888e31602e17b8856c77a3826bf8c841erepo sync{
937960d9f888e31602e17b8856c77a3826bf8c841erepo sync    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
947960d9f888e31602e17b8856c77a3826bf8c841erepo sync    return parcel ? parcel->dataSize() : 0;
95e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti}
96e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti
97e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colittistatic jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jlong nativePtr)
98e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti{
99e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
10059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    return parcel ? parcel->dataAvail() : 0;
10159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt}
102b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran
10359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwaltstatic jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jlong nativePtr)
10459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt{
10559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
10659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    return parcel ? parcel->dataPosition() : 0;
107b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran}
1083b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
1093b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwaltstatic jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr)
1109d9b74a900696191048aa97cc3c854072640428bsy.yun{
1119d9b74a900696191048aa97cc3c854072640428bsy.yun    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
1129d9b74a900696191048aa97cc3c854072640428bsy.yun    return parcel ? parcel->dataCapacity() : 0;
1139d9b74a900696191048aa97cc3c854072640428bsy.yun}
1149d9b74a900696191048aa97cc3c854072640428bsy.yun
115873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
116873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat{
117873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
118873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    if (parcel != NULL) {
119873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        const status_t err = parcel->setDataSize(size);
120873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        if (err != NO_ERROR) {
121873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat            signalExceptionForError(env, clazz, err);
122873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        }
123873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
124873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
125873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
126873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jlong nativePtr, jint pos)
127873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat{
128873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
129873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    if (parcel != NULL) {
130873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        parcel->setDataPosition(pos);
131873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
132873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
133873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
134873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
135bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt{
136873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
137bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt    if (parcel != NULL) {
138873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        const status_t err = parcel->setDataCapacity(size);
139873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        if (err != NO_ERROR) {
140873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat            signalExceptionForError(env, clazz, err);
141873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        }
142873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
143873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
144873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
145873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean allowFds)
146873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat{
147873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
148873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    jboolean ret = JNI_TRUE;
149873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    if (parcel != NULL) {
150873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        ret = (jboolean)parcel->pushAllowFds(allowFds);
151873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
152873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    return ret;
153873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
154873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
155873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean lastValue)
156873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat{
157873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
158873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    if (parcel != NULL) {
159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        parcel->restoreAllowFds((bool)lastValue);
160873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
161873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
162873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
163873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
164873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat                                          jint offset, jint length)
165873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat{
166873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
167b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti    if (parcel == NULL) {
168873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        return;
169873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
170b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti
171873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    const status_t err = parcel->writeInt32(length);
172873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    if (err != NO_ERROR) {
173873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        signalExceptionForError(env, clazz, err);
174873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        return;
17535e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti    }
17635e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti
17735e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti    void* dest = parcel->writeInplace(length);
17835e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti    if (dest == NULL) {
17935e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti        signalExceptionForError(env, clazz, NO_MEMORY);
18035e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti        return;
18135e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti    }
18235e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti
18335e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
18435e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti    if (ar) {
18535e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti        memcpy(dest, ar + offset, length);
18635e36db1d726f5741e7d8d83d2556e1417642be9Lorenzo Colitti        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
187873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
188873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
189873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
190873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatstatic void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
191873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
192873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    const status_t err = parcel->writeInt32(val);
193873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    if (err != NO_ERROR) {
194873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        signalExceptionForError(env, clazz, err);
195873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
196873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
19772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat
19872759df749bb8557269db86c2e3b2a8a0343cc26San Mehatstatic void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jlong nativePtr, jlong val)
19972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat{
20072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
20172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    if (parcel != NULL) {
20272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        const status_t err = parcel->writeInt64(val);
20372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        if (err != NO_ERROR) {
20472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat            signalExceptionForError(env, clazz, err);
20572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        }
20672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    }
20772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat}
20872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat
20972759df749bb8557269db86c2e3b2a8a0343cc26San Mehatstatic void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jlong nativePtr, jfloat val)
21072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat{
211d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
212d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    if (parcel != NULL) {
21372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        const status_t err = parcel->writeFloat(val);
21472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        if (err != NO_ERROR) {
21572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat            signalExceptionForError(env, clazz, err);
21672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        }
21772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    }
21872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat}
219ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt
220cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffstatic void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativePtr, jdouble val)
221cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff{
222cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
223cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    if (parcel != NULL) {
224cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        const status_t err = parcel->writeDouble(val);
225cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        if (err != NO_ERROR) {
2265321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff            signalExceptionForError(env, clazz, err);
2275321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff        }
22890542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff    }
2295321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff}
2305321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff
2315321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriffstatic void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
2325321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff{
23390542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
2345321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff    if (parcel != NULL) {
235c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff        status_t err = NO_MEMORY;
236c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff        if (val) {
237c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff            const jchar* str = env->GetStringCritical(val, 0);
23890542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff            if (str) {
23991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat                err = parcel->writeString16(str, env->GetStringLength(val));
24091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat                env->ReleaseStringCritical(val, str);
2419a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey            }
2429a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey        } else {
2439a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey            err = parcel->writeString16(NULL, 0);
2449a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey        }
2459a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey        if (err != NO_ERROR) {
2469a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey            signalExceptionForError(env, clazz, err);
24791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat        }
248e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    }
249e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey}
25091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat
25191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehatstatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
2529a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey{
2539a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
25491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat    if (parcel != NULL) {
2559a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
25691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat        if (err != NO_ERROR) {
25791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat            signalExceptionForError(env, clazz, err);
258eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey        }
259eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    }
260eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey}
261eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey
262eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeystatic void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
263eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey{
264e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
265cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    if (parcel != NULL) {
266e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey        const status_t err =
267cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
268cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        if (err != NO_ERROR) {
269b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            signalExceptionForError(env, clazz, err);
27050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        }
27141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
272b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey}
273b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
274b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeystatic jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr)
275b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey{
276b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    jbyteArray ret = NULL;
27750fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma
27850fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
27941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    if (parcel != NULL) {
28041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        int32_t len = parcel->readInt32();
28141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
28241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // sanity check the stored length against the true data size
28341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
28441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            ret = env->NewByteArray(len);
28541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
28641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            if (ret != NULL) {
28741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
28841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                if (a2) {
28941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                    const void* data = parcel->readInplace(len);
29041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                    memcpy(a2, data, len);
29141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
29241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                }
29341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
29450fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        }
29550fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma    }
29665be3025fd07d53137f5434794d1d1b3a0933aabFelipe Leme
29765be3025fd07d53137f5434794d1d1b3a0933aabFelipe Leme    return ret;
29865be3025fd07d53137f5434794d1d1b3a0933aabFelipe Leme}
29950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma
300605eb79c9519307147fc1795d0eb155638a7f542Jeff Sharkeystatic jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jlong nativePtr)
301605eb79c9519307147fc1795d0eb155638a7f542Jeff Sharkey{
30250fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
30363d27a9233fed934340231f438493746084a681dJeff Sharkey    if (parcel != NULL) {
30463d27a9233fed934340231f438493746084a681dJeff Sharkey        return parcel->readInt32();
30563d27a9233fed934340231f438493746084a681dJeff Sharkey    }
30663d27a9233fed934340231f438493746084a681dJeff Sharkey    return 0;
30763d27a9233fed934340231f438493746084a681dJeff Sharkey}
3080412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
3090412423f06ec633203b96f68b51f0720c33a2473Haoyu Baistatic jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jlong nativePtr)
3100412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai{
3110412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
3120412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    if (parcel != NULL) {
3130412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        return parcel->readInt64();
31477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    }
3150412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    return 0;
3160412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai}
3170412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
3180412423f06ec633203b96f68b51f0720c33a2473Haoyu Baistatic jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jlong nativePtr)
31977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn{
3200412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
3210412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    if (parcel != NULL) {
3220412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        return parcel->readFloat();
3230412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    }
3240412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    return 0;
3250412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai}
3260412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
3278e48e67827dd2da40e0b28977a9afca0f43de73dPierre Imaistatic jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jlong nativePtr)
3288e48e67827dd2da40e0b28977a9afca0f43de73dPierre Imai{
3298e48e67827dd2da40e0b28977a9afca0f43de73dPierre Imai    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
3308e48e67827dd2da40e0b28977a9afca0f43de73dPierre Imai    if (parcel != NULL) {
3318e48e67827dd2da40e0b28977a9afca0f43de73dPierre Imai        return parcel->readDouble();
33213e817df516a803fbedeacca2c802a9fc1c1370fPaul Jensen    }
3337475c0cea622f126af966c3b5b9741f547e83450Mattias Falk    return 0;
33413e817df516a803fbedeacca2c802a9fc1c1370fPaul Jensen}
3357475c0cea622f126af966c3b5b9741f547e83450Mattias Falk
336c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkeystatic jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr)
337c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey{
3382c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
3392c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey    if (parcel != NULL) {
3402c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey        size_t len;
341b41c9f7f39939cee8d226eb5e506c3f0573f44f5Xiaohui Chen        const char16_t* str = parcel->readString16Inplace(&len);
342b41c9f7f39939cee8d226eb5e506c3f0573f44f5Xiaohui Chen        if (str) {
343b41c9f7f39939cee8d226eb5e506c3f0573f44f5Xiaohui Chen            return env->NewString(str, len);
3448b47b3601f82f299bb8c135af0639b72b67230e6Mattias Falk        }
3458b47b3601f82f299bb8c135af0639b72b67230e6Mattias Falk        return NULL;
3466bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
3473277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker    return NULL;
3486bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen}
3493277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker
3503277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubakerstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
3516bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen{
3523277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
3536bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    if (parcel != NULL) {
3543277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker        return javaObjectForIBinder(env, parcel->readStrongBinder());
3553277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker    }
356954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    return NULL;
35779751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti}
35879751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
35979751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colittistatic jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr)
36079751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti{
361954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
36279751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    if (parcel != NULL) {
363954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti        int fd = parcel->readFileDescriptor();
36479751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        if (fd < 0) return NULL;
36579751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        fd = dup(fd);
366954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti        if (fd < 0) return NULL;
36779751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        return jniCreateFileDescriptor(env, fd);
368954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    }
36977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    return NULL;
37077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn}
37177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
37277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackbornstatic jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
37377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                                                    jstring name, jint mode)
37477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn{
37577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    if (name == NULL) {
37677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        jniThrowNullPointerException(env, NULL);
37777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        return NULL;
37877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    }
37977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    const jchar* str = env->GetStringCritical(name, 0);
38077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    if (str == NULL) {
38177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        // Whatever, whatever.
38277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        jniThrowException(env, "java/lang/IllegalStateException", NULL);
38377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        return NULL;
3849ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt    }
3859ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt    String8 name8(str, env->GetStringLength(name));
3866bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    env->ReleaseStringCritical(name, str);
387487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen    int flags=0;
388487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen    switch (mode&0x30000000) {
3896bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        case 0:
390487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen        case 0x10000000:
3916bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            flags = O_RDONLY;
3926bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            break;
3936bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        case 0x20000000:
3949ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt            flags = O_WRONLY;
3958cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran            break;
3969ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        case 0x30000000:
3979ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt            flags = O_RDWR;
398992f25257938ecc0378514f21c6e6e6375272976Paul Jensen            break;
3999ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt    }
4009ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt
401568891d9282383747c418a59ee714281726f390aRobert Greenwalt    if (mode&0x08000000) flags |= O_CREAT;
402992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    if (mode&0x04000000) flags |= O_TRUNC;
403992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    if (mode&0x02000000) flags |= O_APPEND;
404992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
405992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    int realMode = S_IRWXU|S_IRWXG;
406992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    if (mode&0x00000001) realMode |= S_IROTH;
407992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    if (mode&0x00000002) realMode |= S_IWOTH;
408992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
409992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    int fd = open(name8.string(), flags, realMode);
410992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    if (fd < 0) {
411992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
412913c895216c0cb248ed0ce910e69dd84b285c064Robert Greenwalt        return NULL;
413568891d9282383747c418a59ee714281726f390aRobert Greenwalt    }
414f047f2a8f49cd06d9cb94238861f4acce937d87bSreeram Ramachandran    jobject object = jniCreateFileDescriptor(env, fd);
415568891d9282383747c418a59ee714281726f390aRobert Greenwalt    if (object == NULL) {
416568891d9282383747c418a59ee714281726f390aRobert Greenwalt        close(fd);
417487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen    }
418487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen    return object;
419487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen}
420487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen
421487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensenstatic jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
422487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen{
423487ffe7d3d84bf65212158f7098e8a84b5b55e09Paul Jensen    if (orig == NULL) {
424e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        jniThrowNullPointerException(env, NULL);
425568891d9282383747c418a59ee714281726f390aRobert Greenwalt        return NULL;
4266bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
4276bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    int origfd = jniGetFDFromFileDescriptor(env, orig);
4286bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    if (origfd < 0) {
4296bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
4306bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        return NULL;
4316bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
4326bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
4336bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    int fd = dup(origfd);
4346bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    if (fd < 0) {
4356bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        jniThrowIOException(env, errno);
436a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        return NULL;
437a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    }
438a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    jobject object = jniCreateFileDescriptor(env, fd);
43917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee    if (object == NULL) {
44017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee        close(fd);
441873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
442    return object;
443}
444
445static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
446{
447    if (object == NULL) {
448        jniThrowNullPointerException(env, NULL);
449        return;
450    }
451    int fd = jniGetFDFromFileDescriptor(env, object);
452    if (fd >= 0) {
453        jniSetFileDescriptorOfFD(env, object, -1);
454        //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
455        close(fd);
456    }
457}
458
459static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
460{
461    if (object == NULL) {
462        jniThrowNullPointerException(env, NULL);
463        return;
464    }
465    int fd = jniGetFDFromFileDescriptor(env, object);
466    if (fd >= 0) {
467        jniSetFileDescriptorOfFD(env, object, -1);
468    }
469}
470
471static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
472{
473    Parcel* parcel = new Parcel();
474    return reinterpret_cast<jlong>(parcel);
475}
476
477static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
478{
479    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
480    if (parcel != NULL) {
481        parcel->freeData();
482    }
483}
484
485static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr)
486{
487    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
488    delete parcel;
489}
490
491static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
492{
493    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
494    if (parcel == NULL) {
495       return NULL;
496    }
497
498    // do not marshall if there are binder objects in the parcel
499    if (parcel->objectsCount())
500    {
501        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
502        return NULL;
503    }
504
505    jbyteArray ret = env->NewByteArray(parcel->dataSize());
506
507    if (ret != NULL)
508    {
509        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
510        if (array != NULL)
511        {
512            memcpy(array, parcel->data(), parcel->dataSize());
513            env->ReleasePrimitiveArrayCritical(ret, array, 0);
514        }
515    }
516
517    return ret;
518}
519
520static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
521                                         jbyteArray data, jint offset, jint length)
522{
523    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
524    if (parcel == NULL || length < 0) {
525       return;
526    }
527
528    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
529    if (array)
530    {
531        parcel->setDataSize(length);
532        parcel->setDataPosition(0);
533
534        void* raw = parcel->writeInplace(length);
535        memcpy(raw, (array + offset), length);
536
537        env->ReleasePrimitiveArrayCritical(data, array, 0);
538    }
539}
540
541static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
542                                         jlong otherNativePtr, jint offset, jint length)
543{
544    Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
545    if (thisParcel == NULL) {
546       return;
547    }
548    Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
549    if (otherParcel == NULL) {
550       return;
551    }
552
553    status_t err = thisParcel->appendFrom(otherParcel, offset, length);
554    if (err != NO_ERROR) {
555        signalExceptionForError(env, clazz, err);
556    }
557}
558
559static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jlong nativePtr)
560{
561    jboolean ret = JNI_FALSE;
562    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
563    if (parcel != NULL) {
564        if (parcel->hasFileDescriptors()) {
565            ret = JNI_TRUE;
566        }
567    }
568    return ret;
569}
570
571static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr,
572                                                  jstring name)
573{
574    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
575    if (parcel != NULL) {
576        // In the current implementation, the token is just the serialized interface name that
577        // the caller expects to be invoking
578        const jchar* str = env->GetStringCritical(name, 0);
579        if (str != NULL) {
580            parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
581            env->ReleaseStringCritical(name, str);
582        }
583    }
584}
585
586static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
587{
588    jboolean ret = JNI_FALSE;
589
590    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
591    if (parcel != NULL) {
592        const jchar* str = env->GetStringCritical(name, 0);
593        if (str) {
594            IPCThreadState* threadState = IPCThreadState::self();
595            const int32_t oldPolicy = threadState->getStrictModePolicy();
596            const bool isValid = parcel->enforceInterface(
597                String16(str, env->GetStringLength(name)),
598                threadState);
599            env->ReleaseStringCritical(name, str);
600            if (isValid) {
601                const int32_t newPolicy = threadState->getStrictModePolicy();
602                if (oldPolicy != newPolicy) {
603                    // Need to keep the Java-level thread-local strict
604                    // mode policy in sync for the libcore
605                    // enforcements, which involves an upcall back
606                    // into Java.  (We can't modify the
607                    // Parcel.enforceInterface signature, as it's
608                    // pseudo-public, and used via AIDL
609                    // auto-generation...)
610                    set_dalvik_blockguard_policy(env, newPolicy);
611                }
612                return;     // everything was correct -> return silently
613            }
614        }
615    }
616
617    // all error conditions wind up here
618    jniThrowException(env, "java/lang/SecurityException",
619            "Binder invocation to an incorrect interface");
620}
621
622// ----------------------------------------------------------------------------
623
624static const JNINativeMethod gParcelMethods[] = {
625    {"nativeDataSize",            "(J)I", (void*)android_os_Parcel_dataSize},
626    {"nativeDataAvail",           "(J)I", (void*)android_os_Parcel_dataAvail},
627    {"nativeDataPosition",        "(J)I", (void*)android_os_Parcel_dataPosition},
628    {"nativeDataCapacity",        "(J)I", (void*)android_os_Parcel_dataCapacity},
629    {"nativeSetDataSize",         "(JI)V", (void*)android_os_Parcel_setDataSize},
630    {"nativeSetDataPosition",     "(JI)V", (void*)android_os_Parcel_setDataPosition},
631    {"nativeSetDataCapacity",     "(JI)V", (void*)android_os_Parcel_setDataCapacity},
632
633    {"nativePushAllowFds",        "(JZ)Z", (void*)android_os_Parcel_pushAllowFds},
634    {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
635
636    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeNative},
637    {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
638    {"nativeWriteLong",           "(JJ)V", (void*)android_os_Parcel_writeLong},
639    {"nativeWriteFloat",          "(JF)V", (void*)android_os_Parcel_writeFloat},
640    {"nativeWriteDouble",         "(JD)V", (void*)android_os_Parcel_writeDouble},
641    {"nativeWriteString",         "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
642    {"nativeWriteStrongBinder",   "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
643    {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
644
645    {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
646    {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},
647    {"nativeReadLong",            "(J)J", (void*)android_os_Parcel_readLong},
648    {"nativeReadFloat",           "(J)F", (void*)android_os_Parcel_readFloat},
649    {"nativeReadDouble",          "(J)D", (void*)android_os_Parcel_readDouble},
650    {"nativeReadString",          "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
651    {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
652    {"nativeReadFileDescriptor",  "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
653
654    {"openFileDescriptor",        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
655    {"dupFileDescriptor",         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
656    {"closeFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
657    {"clearFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
658
659    {"nativeCreate",              "()J", (void*)android_os_Parcel_create},
660    {"nativeFreeBuffer",          "(J)V", (void*)android_os_Parcel_freeBuffer},
661    {"nativeDestroy",             "(J)V", (void*)android_os_Parcel_destroy},
662
663    {"nativeMarshall",            "(J)[B", (void*)android_os_Parcel_marshall},
664    {"nativeUnmarshall",          "(J[BII)V", (void*)android_os_Parcel_unmarshall},
665    {"nativeAppendFrom",          "(JJII)V", (void*)android_os_Parcel_appendFrom},
666    {"nativeHasFileDescriptors",  "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
667    {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
668    {"nativeEnforceInterface",    "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
669};
670
671const char* const kParcelPathName = "android/os/Parcel";
672
673int register_android_os_Parcel(JNIEnv* env)
674{
675    jclass clazz;
676
677    clazz = env->FindClass(kParcelPathName);
678    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
679
680    gParcelOffsets.clazz = (jclass) env->NewGlobalRef(clazz);
681    gParcelOffsets.mNativePtr = env->GetFieldID(clazz, "mNativePtr", "J");
682    gParcelOffsets.obtain = env->GetStaticMethodID(clazz, "obtain",
683                                                   "()Landroid/os/Parcel;");
684    gParcelOffsets.recycle = env->GetMethodID(clazz, "recycle", "()V");
685
686    return AndroidRuntime::registerNativeMethods(
687        env, kParcelPathName,
688        gParcelMethods, NELEM(gParcelMethods));
689}
690
691};
692