1d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey/*
2d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * Copyright (C) 2012 The Android Open Source Project
3d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey *
4d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * you may not use this file except in compliance with the License.
6d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * You may obtain a copy of the License at
7d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey *
8d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey *
10d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * See the License for the specific language governing permissions and
14d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey * limitations under the License.
15d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey */
16d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
17d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOG_TAG "Parcel"
18d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#define LOG_NDEBUG 0
19d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
20d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "android_os_Parcel.h"
21d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "android_util_Binder.h"
22d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
23d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "JNIHelp.h"
24d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
25d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <fcntl.h>
26d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <stdio.h>
27d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <sys/stat.h>
28d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <sys/types.h>
29d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <unistd.h>
30d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
31d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/Atomic.h>
32d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/IInterface.h>
33d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/IPCThreadState.h>
34d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/Log.h>
35d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/SystemClock.h>
36d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/List.h>
37d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/KeyedVector.h>
38d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <cutils/logger.h>
39d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/Parcel.h>
40d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/ProcessState.h>
41d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/IServiceManager.h>
42d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/threads.h>
43d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/String8.h>
44d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
45d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <ScopedUtfChars.h>
46d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <ScopedLocalRef.h>
47d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
48d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <android_runtime/AndroidRuntime.h>
49d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
50d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#undef ALOGV
51d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
52d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
53d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define DEBUG_DEATH 0
54d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#if DEBUG_DEATH
55d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOGDEATH ALOGD
56d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#else
57d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOGDEATH ALOGV
58d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#endif
59d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
60d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeynamespace android {
61d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
62d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic struct parcel_offsets_t
63d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
648902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jclass clazz;
65047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    jfieldID mNativePtr;
668902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jmethodID obtain;
678902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jmethodID recycle;
68d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey} gParcelOffsets;
69d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
70d84e1ce0b535128f03416145554fb405f9fade3eJeff SharkeyParcel* parcelForJavaObject(JNIEnv* env, jobject obj)
71d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
72d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (obj) {
73047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey        Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mNativePtr);
74d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (p != NULL) {
75d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return p;
76d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
77d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
78d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
79d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
80d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
81d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
828902097bb686752ff207e3bda12713be1a8c74ebInsun Kangjobject createJavaParcelObject(JNIEnv* env)
838902097bb686752ff207e3bda12713be1a8c74ebInsun Kang{
848902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain);
858902097bb686752ff207e3bda12713be1a8c74ebInsun Kang}
868902097bb686752ff207e3bda12713be1a8c74ebInsun Kang
878902097bb686752ff207e3bda12713be1a8c74ebInsun Kangvoid recycleJavaParcelObject(JNIEnv* env, jobject parcelObj)
888902097bb686752ff207e3bda12713be1a8c74ebInsun Kang{
898902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
908902097bb686752ff207e3bda12713be1a8c74ebInsun Kang}
918902097bb686752ff207e3bda12713be1a8c74ebInsun Kang
92047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jint nativePtr)
93d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
94047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
95d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataSize() : 0;
96d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
97d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
98047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jint nativePtr)
99d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
100047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
101d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataAvail() : 0;
102d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
103d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
104047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jint nativePtr)
105d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
106047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
107d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataPosition() : 0;
108d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
109d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
110047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jint nativePtr)
111d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
112047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
113d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataCapacity() : 0;
114d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
115d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
116047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jint nativePtr, jint size)
117d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
118047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
119d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
120d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataSize(size);
121d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
122d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
123d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
124d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
125d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
126d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
127047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jint nativePtr, jint pos)
128d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
129047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
130d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
131d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(pos);
132d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
133d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
134d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
135047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jint nativePtr, jint size)
136d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
137047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
138d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
139d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataCapacity(size);
140d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
141d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
142d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
143d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
144d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
145d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
146047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean allowFds)
147d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
148047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
149d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_TRUE;
150d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
151d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        ret = (jboolean)parcel->pushAllowFds(allowFds);
152d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
153d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
154d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
155d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
156047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean lastValue)
157d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
158047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
159d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
160d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->restoreAllowFds((bool)lastValue);
161d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
162d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
163d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
164047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jint nativePtr, jobject data,
165047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                          jint offset, jint length)
166d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
167047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
168d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
169d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
170d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
171d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
172d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const status_t err = parcel->writeInt32(length);
173d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
174d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
175d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
176d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
177d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
178d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    void* dest = parcel->writeInplace(length);
179d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (dest == NULL) {
180d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, NO_MEMORY);
181d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
182d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
183d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
184d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
185d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ar) {
186d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(dest, ar + offset, length);
187d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
188d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
189d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
190d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
191047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jint nativePtr, jint val) {
192047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
193047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    const status_t err = parcel->writeInt32(val);
194047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    if (err != NO_ERROR) {
195047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey        signalExceptionForError(env, clazz, err);
196d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
197d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
198d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
199047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jint nativePtr, jlong val)
200d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
201047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
202d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
203d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeInt64(val);
204d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
205d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
206d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
207d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
208d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
209d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
210047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jint nativePtr, jfloat val)
211d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
212047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
213d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
214d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeFloat(val);
215d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
216d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
217d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
218d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
219d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
220d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
221047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jint nativePtr, jdouble val)
222d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
223047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
224d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
225d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeDouble(val);
226d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
227d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
228d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
229d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
230d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
231d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
232047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint nativePtr, jstring val)
233d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
234047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
235d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
236d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        status_t err = NO_MEMORY;
237d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (val) {
238d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const jchar* str = env->GetStringCritical(val, 0);
239d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (str) {
240d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                err = parcel->writeString16(str, env->GetStringLength(val));
241d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                env->ReleaseStringCritical(val, str);
242d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
243d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        } else {
244d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            err = parcel->writeString16(NULL, 0);
245d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
246d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
247d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
248d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
249d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
250d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
251d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
252047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
253d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
254047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
255d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
256d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
257d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
258d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
259d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
260d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
261d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
262d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
263047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
264d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
265047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
266d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
267d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err =
268d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
269d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
270d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
271d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
272d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
273d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
274d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
275047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jint nativePtr)
276d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
277d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = NULL;
278d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
279047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
280d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
281d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int32_t len = parcel->readInt32();
282d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
283d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // sanity check the stored length against the true data size
284d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
285d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = env->NewByteArray(len);
286d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
287d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (ret != NULL) {
288d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
289d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (a2) {
290d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    const void* data = parcel->readInplace(len);
291d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    memcpy(a2, data, len);
292d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
293d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
294d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
295d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
296d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
297d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
298d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
299d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
300d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
301047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jint nativePtr)
302d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
303047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
304d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
305d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt32();
306d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
307d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
308d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
309d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
310047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jint nativePtr)
311d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
312047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
313d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
314d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt64();
315d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
316d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
317d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
318d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
319047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jint nativePtr)
320d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
321047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
322d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
323d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readFloat();
324d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
325d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
326d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
327d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
328047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jint nativePtr)
329d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
330047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
331d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
332d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readDouble();
333d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
334d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
335d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
336d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
337047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jint nativePtr)
338d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
339047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
340d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
341d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        size_t len;
342d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const char16_t* str = parcel->readString16Inplace(&len);
343d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
344d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return env->NewString(str, len);
345d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
346d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
347d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
348d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
349d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
350d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
351047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr)
352d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
353047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
354d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
355d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return javaObjectForIBinder(env, parcel->readStrongBinder());
356d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
357d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
358d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
359d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
360047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr)
361d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
362047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
363d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
364d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int fd = parcel->readFileDescriptor();
365d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
366d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        fd = dup(fd);
367d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
368d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return jniCreateFileDescriptor(env, fd);
369d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
370d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
371d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
372d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
373047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
374d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                                                    jstring name, jint mode)
375d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
376d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (name == NULL) {
377d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
378d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
379d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
380d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const jchar* str = env->GetStringCritical(name, 0);
381d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (str == NULL) {
382d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // Whatever, whatever.
383d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", NULL);
384d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
385d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
386d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    String8 name8(str, env->GetStringLength(name));
387d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    env->ReleaseStringCritical(name, str);
388d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int flags=0;
389d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    switch (mode&0x30000000) {
390d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0:
391d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x10000000:
392d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDONLY;
393d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
394d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x20000000:
395d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_WRONLY;
396d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
397d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x30000000:
398d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDWR;
399d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
400d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
401d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
402d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x08000000) flags |= O_CREAT;
403d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x04000000) flags |= O_TRUNC;
404d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x02000000) flags |= O_APPEND;
405d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
406d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int realMode = S_IRWXU|S_IRWXG;
407d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000001) realMode |= S_IROTH;
408d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000002) realMode |= S_IWOTH;
409d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
410d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = open(name8.string(), flags, realMode);
411d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
412d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
413d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
414d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
415d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
416d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
417d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
418d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
419d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
420d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
421d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
422047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
423d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
424d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (orig == NULL) {
425d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
426d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
427d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
428d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int origfd = jniGetFDFromFileDescriptor(env, orig);
429d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (origfd < 0) {
430d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
431d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
432d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
433d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
434d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = dup(origfd);
435d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
436d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowIOException(env, errno);
437d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
438d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
439d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
440d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
441d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
442d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
443d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
444d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
445d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
446047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
447d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
448d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
449d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
450d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
451d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
452d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
453d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
454d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
455d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
456d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
457d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
458d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
459d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
460047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
461d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
462d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
463d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
464d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
465d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
466d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
467d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
468d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
469d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
470d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
471d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
472047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jint android_os_Parcel_create(JNIEnv* env, jclass clazz)
473d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
474047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = new Parcel();
475047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    return reinterpret_cast<jint>(parcel);
476d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
477d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
478047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jint nativePtr)
479d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
480047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
481047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    if (parcel != NULL) {
482047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey        parcel->freeData();
483d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
484d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
485d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
486047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jint nativePtr)
487d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
488047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
489047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    delete parcel;
490d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
491d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
492047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jint nativePtr)
493d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
494047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
495d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
496d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return NULL;
497d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
498d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
499d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // do not marshall if there are binder objects in the parcel
500d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel->objectsCount())
501d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
502d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
503d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
504d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
505d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
506d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = env->NewByteArray(parcel->dataSize());
507d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
508d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ret != NULL)
509d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
510d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
511d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (array != NULL)
512d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        {
513d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            memcpy(array, parcel->data(), parcel->dataSize());
514d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleasePrimitiveArrayCritical(ret, array, 0);
515d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
516d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
517d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
518d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
519d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
520d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
521047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jint nativePtr,
522047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                         jbyteArray data, jint offset, jint length)
523d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
524047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
525d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL || length < 0) {
526d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
527d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
528d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
529d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
530d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (array)
531d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
532d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataSize(length);
533d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(0);
534d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
535d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        void* raw = parcel->writeInplace(length);
536d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(raw, (array + offset), length);
537d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
538d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical(data, array, 0);
539d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
540d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
541d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
542047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jint thisNativePtr,
543047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                         jint otherNativePtr, jint offset, jint length)
544d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
545047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
546d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (thisParcel == NULL) {
547d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
548d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
549047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
550d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (otherParcel == NULL) {
551d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
552d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
553d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
554d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    status_t err = thisParcel->appendFrom(otherParcel, offset, length);
555d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
556d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
557d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
558d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
559d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
560047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jint nativePtr)
561d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
562d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
563047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
564d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
565d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (parcel->hasFileDescriptors()) {
566d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = JNI_TRUE;
567d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
568d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
569d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
570d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
571d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
572047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jint nativePtr,
573047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                                  jstring name)
574d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
575047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
576d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
577d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // In the current implementation, the token is just the serialized interface name that
578d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // the caller expects to be invoking
579d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
580d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str != NULL) {
581d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
582d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
583d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
584d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
585d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
586d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
587047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jint nativePtr, jstring name)
588d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
589d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
590d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
591047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
592d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
593d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
594d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
595d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            IPCThreadState* threadState = IPCThreadState::self();
596d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const int32_t oldPolicy = threadState->getStrictModePolicy();
597d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const bool isValid = parcel->enforceInterface(
598d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                String16(str, env->GetStringLength(name)),
599d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                threadState);
600d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
601d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (isValid) {
602d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                const int32_t newPolicy = threadState->getStrictModePolicy();
603d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (oldPolicy != newPolicy) {
604d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Need to keep the Java-level thread-local strict
605d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // mode policy in sync for the libcore
606d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // enforcements, which involves an upcall back
607d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // into Java.  (We can't modify the
608d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Parcel.enforceInterface signature, as it's
609d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // pseudo-public, and used via AIDL
610d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // auto-generation...)
611d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    set_dalvik_blockguard_policy(env, newPolicy);
612d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
613d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                return;     // everything was correct -> return silently
614d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
615d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
616d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
617d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
618d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // all error conditions wind up here
619d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jniThrowException(env, "java/lang/SecurityException",
620d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            "Binder invocation to an incorrect interface");
621d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
622d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
623d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey// ----------------------------------------------------------------------------
624d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
625d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic const JNINativeMethod gParcelMethods[] = {
626047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeDataSize",            "(I)I", (void*)android_os_Parcel_dataSize},
627047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeDataAvail",           "(I)I", (void*)android_os_Parcel_dataAvail},
628047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeDataPosition",        "(I)I", (void*)android_os_Parcel_dataPosition},
629047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeDataCapacity",        "(I)I", (void*)android_os_Parcel_dataCapacity},
630047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeSetDataSize",         "(II)V", (void*)android_os_Parcel_setDataSize},
631047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeSetDataPosition",     "(II)V", (void*)android_os_Parcel_setDataPosition},
632047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeSetDataCapacity",     "(II)V", (void*)android_os_Parcel_setDataCapacity},
633047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
634047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativePushAllowFds",        "(IZ)Z", (void*)android_os_Parcel_pushAllowFds},
635047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeRestoreAllowFds",     "(IZ)V", (void*)android_os_Parcel_restoreAllowFds},
636047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
637047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteByteArray",      "(I[BII)V", (void*)android_os_Parcel_writeNative},
638047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteInt",            "(II)V", (void*)android_os_Parcel_writeInt},
639047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteLong",           "(IJ)V", (void*)android_os_Parcel_writeLong},
640047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteFloat",          "(IF)V", (void*)android_os_Parcel_writeFloat},
641047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteDouble",         "(ID)V", (void*)android_os_Parcel_writeDouble},
642047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteString",         "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeString},
643047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteStrongBinder",   "(ILandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
644047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteFileDescriptor", "(ILjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
645047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
646047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeCreateByteArray",     "(I)[B", (void*)android_os_Parcel_createByteArray},
647047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadInt",             "(I)I", (void*)android_os_Parcel_readInt},
648047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadLong",            "(I)J", (void*)android_os_Parcel_readLong},
649047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadFloat",           "(I)F", (void*)android_os_Parcel_readFloat},
650047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadDouble",          "(I)D", (void*)android_os_Parcel_readDouble},
651047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadString",          "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString},
652047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadStrongBinder",    "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
653047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeReadFileDescriptor",  "(I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
654047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
655047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"openFileDescriptor",        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
656047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"dupFileDescriptor",         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
657047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"closeFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
658047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"clearFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
659047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
660047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeCreate",              "()I", (void*)android_os_Parcel_create},
661047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeFreeBuffer",          "(I)V", (void*)android_os_Parcel_freeBuffer},
662047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeDestroy",             "(I)V", (void*)android_os_Parcel_destroy},
663047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
664047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeMarshall",            "(I)[B", (void*)android_os_Parcel_marshall},
665047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeUnmarshall",          "(I[BII)V", (void*)android_os_Parcel_unmarshall},
666047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeAppendFrom",          "(IIII)V", (void*)android_os_Parcel_appendFrom},
667047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeHasFileDescriptors",  "(I)Z", (void*)android_os_Parcel_hasFileDescriptors},
668047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeWriteInterfaceToken", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
669047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"nativeEnforceInterface",    "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
670d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
671d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
672d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyconst char* const kParcelPathName = "android/os/Parcel";
673d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
674d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyint register_android_os_Parcel(JNIEnv* env)
675d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
676d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jclass clazz;
677d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
678d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    clazz = env->FindClass(kParcelPathName);
679d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
680d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6818902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.clazz = (jclass) env->NewGlobalRef(clazz);
6828902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.mNativePtr = env->GetFieldID(clazz, "mNativePtr", "I");
6838902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.obtain = env->GetStaticMethodID(clazz, "obtain",
6848902097bb686752ff207e3bda12713be1a8c74ebInsun Kang                                                   "()Landroid/os/Parcel;");
6858902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.recycle = env->GetMethodID(clazz, "recycle", "()V");
686d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
687d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return AndroidRuntime::registerNativeMethods(
688d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env, kParcelPathName,
689d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        gParcelMethods, NELEM(gParcelMethods));
690d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
691d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
692d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
693