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