android_os_Parcel.cpp revision d84e1ce0b535128f03416145554fb405f9fade3e
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{
64d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jfieldID mObject;
65d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jfieldID mOwnObject;
66d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey} gParcelOffsets;
67d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
68d84e1ce0b535128f03416145554fb405f9fade3eJeff SharkeyParcel* parcelForJavaObject(JNIEnv* env, jobject obj)
69d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
70d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (obj) {
71d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject);
72d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (p != NULL) {
73d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return p;
74d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
75d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
76d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
77d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
78d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
79d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
80d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz)
81d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
82d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
83d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataSize() : 0;
84d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
85d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
86d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz)
87d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
88d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
89d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataAvail() : 0;
90d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
91d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
92d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz)
93d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
94d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
95d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataPosition() : 0;
96d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
97d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
98d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz)
99d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
100d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
101d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataCapacity() : 0;
102d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
103d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
104d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
105d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
106d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
107d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
108d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataSize(size);
109d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
110d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
111d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
112d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
113d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
114d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
115d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos)
116d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
117d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
118d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
119d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(pos);
120d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
121d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
122d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
123d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size)
124d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
125d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
126d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
127d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataCapacity(size);
128d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
129d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
130d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
131d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
132d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
133d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
134d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
135d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
136d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
137d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_TRUE;
138d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
139d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        ret = (jboolean)parcel->pushAllowFds(allowFds);
140d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
141d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
142d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
143d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
144d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
145d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
146d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
147d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
148d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->restoreAllowFds((bool)lastValue);
149d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
150d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
151d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
152d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
153d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                                          jobject data, jint offset,
154d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                                          jint length)
155d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
156d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
157d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
158d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
159d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
160d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
161d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const status_t err = parcel->writeInt32(length);
162d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
163d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
164d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
165d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
166d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
167d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    void* dest = parcel->writeInplace(length);
168d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (dest == NULL) {
169d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, NO_MEMORY);
170d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
171d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
172d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
173d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
174d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ar) {
175d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(dest, ar + offset, length);
176d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
177d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
178d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
179d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
180d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
181d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
182d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
183d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
184d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
185d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeInt32(val);
186d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
187d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
188d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
189d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
190d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
191d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
192d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
193d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
194d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
195d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
196d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeInt64(val);
197d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
198d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
199d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
200d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
201d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
202d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
203d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
204d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
205d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
206d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
207d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeFloat(val);
208d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
209d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
210d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
211d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
212d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
213d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
214d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val)
215d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
216d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
217d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
218d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeDouble(val);
219d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
220d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
221d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
222d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
223d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
224d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
225d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
226d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
227d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
228d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
229d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        status_t err = NO_MEMORY;
230d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (val) {
231d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const jchar* str = env->GetStringCritical(val, 0);
232d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (str) {
233d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                err = parcel->writeString16(str, env->GetStringLength(val));
234d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                env->ReleaseStringCritical(val, str);
235d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
236d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        } else {
237d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            err = parcel->writeString16(NULL, 0);
238d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
239d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
240d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
241d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
242d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
243d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
244d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
245d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
246d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
247d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
248d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
249d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
250d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
251d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
252d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
253d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
254d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
255d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
256d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
257d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
258d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
259d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
260d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err =
261d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
262d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
263d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
264d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
265d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
266d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
267d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
268d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
269d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
270d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = NULL;
271d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
272d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
273d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
274d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int32_t len = parcel->readInt32();
275d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
276d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // sanity check the stored length against the true data size
277d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
278d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = env->NewByteArray(len);
279d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
280d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (ret != NULL) {
281d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
282d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (a2) {
283d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    const void* data = parcel->readInplace(len);
284d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    memcpy(a2, data, len);
285d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
286d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
287d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
288d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
289d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
290d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
291d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
292d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
293d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
294d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
295d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
296d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
297d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
298d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt32();
299d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
300d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
301d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
302d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
303d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz)
304d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
305d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
306d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
307d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt64();
308d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
309d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
310d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
311d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
312d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz)
313d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
314d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
315d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
316d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readFloat();
317d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
318d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
319d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
320d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
321d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz)
322d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
323d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
324d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
325d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readDouble();
326d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
327d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
328d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
329d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
330d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
331d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
332d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
333d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
334d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        size_t len;
335d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const char16_t* str = parcel->readString16Inplace(&len);
336d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
337d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return env->NewString(str, len);
338d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
339d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
340d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
341d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
342d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
343d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
344d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
345d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
346d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
347d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
348d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return javaObjectForIBinder(env, parcel->readStrongBinder());
349d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
350d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
351d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
352d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
353d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
354d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
355d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
356d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
357d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int fd = parcel->readFileDescriptor();
358d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
359d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        fd = dup(fd);
360d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
361d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return jniCreateFileDescriptor(env, fd);
362d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
363d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
364d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
365d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
366d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
367d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                                                    jstring name, jint mode)
368d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
369d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (name == NULL) {
370d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
371d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
372d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
373d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const jchar* str = env->GetStringCritical(name, 0);
374d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (str == NULL) {
375d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // Whatever, whatever.
376d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", NULL);
377d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
378d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
379d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    String8 name8(str, env->GetStringLength(name));
380d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    env->ReleaseStringCritical(name, str);
381d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int flags=0;
382d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    switch (mode&0x30000000) {
383d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0:
384d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x10000000:
385d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDONLY;
386d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
387d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x20000000:
388d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_WRONLY;
389d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
390d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x30000000:
391d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDWR;
392d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
393d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
394d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
395d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x08000000) flags |= O_CREAT;
396d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x04000000) flags |= O_TRUNC;
397d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x02000000) flags |= O_APPEND;
398d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
399d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int realMode = S_IRWXU|S_IRWXG;
400d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000001) realMode |= S_IROTH;
401d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000002) realMode |= S_IWOTH;
402d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
403d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = open(name8.string(), flags, realMode);
404d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
405d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
406d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
407d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
408d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
409d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
410d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
411d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
412d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
413d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
414d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
415d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig)
416d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
417d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (orig == NULL) {
418d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
419d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
420d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
421d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int origfd = jniGetFDFromFileDescriptor(env, orig);
422d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (origfd < 0) {
423d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
424d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
425d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
426d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
427d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = dup(origfd);
428d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
429d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowIOException(env, errno);
430d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
431d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
432d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
433d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
434d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
435d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
436d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
437d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
438d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
439d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
440d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
441d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
442d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
443d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
444d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
445d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
446d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
447d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
448d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
449d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
450d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
451d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
452d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
453d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
454d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
455d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
456d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
457d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
458d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
459d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
460d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
461d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
462d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
463d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
464d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
465d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz)
466d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
467d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
468d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (own) {
469d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        Parcel* parcel = parcelForJavaObject(env, clazz);
470d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (parcel != NULL) {
471d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            //ALOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel);
472d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            parcel->freeData();
473d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
474d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
475d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
476d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
477d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
478d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
479d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = (Parcel*)parcelInt;
480d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int own = 0;
481d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (!parcel) {
482d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Initializing obj %p: creating new Parcel\n", clazz);
483d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        own = 1;
484d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel = new Parcel;
485d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    } else {
486d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
487d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
488d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
489d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
490d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
491d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
492d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    //ALOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
493d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
494d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
495d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
496d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
497d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_destroy(JNIEnv* env, jobject clazz)
498d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
499d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
500d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (own) {
501d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        Parcel* parcel = parcelForJavaObject(env, clazz);
502d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->SetIntField(clazz, gParcelOffsets.mObject, 0);
503d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel);
504d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        delete parcel;
505d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    } else {
506d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->SetIntField(clazz, gParcelOffsets.mObject, 0);
507d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz);
508d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
509d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
510d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
511d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
512d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
513d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
514d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
515d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return NULL;
516d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
517d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
518d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // do not marshall if there are binder objects in the parcel
519d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel->objectsCount())
520d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
521d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
522d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
523d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
524d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
525d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = env->NewByteArray(parcel->dataSize());
526d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
527d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ret != NULL)
528d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
529d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
530d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (array != NULL)
531d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        {
532d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            memcpy(array, parcel->data(), parcel->dataSize());
533d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleasePrimitiveArrayCritical(ret, array, 0);
534d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
535d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
536d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
537d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
538d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
539d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
540d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length)
541d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
542d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
543d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL || length < 0) {
544d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
545d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
546d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
547d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
548d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (array)
549d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
550d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataSize(length);
551d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(0);
552d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
553d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        void* raw = parcel->writeInplace(length);
554d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(raw, (array + offset), length);
555d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
556d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical(data, array, 0);
557d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
558d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
559d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
560d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length)
561d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
562d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* thisParcel = parcelForJavaObject(env, clazz);
563d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (thisParcel == NULL) {
564d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
565d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
566d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* otherParcel = parcelForJavaObject(env, parcel);
567d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (otherParcel == NULL) {
568d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
569d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
570d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
571d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    status_t err = thisParcel->appendFrom(otherParcel, offset, length);
572d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
573d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
574d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
575d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
576d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
577d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
578d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
579d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
580d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
581d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
582d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (parcel->hasFileDescriptors()) {
583d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = JNI_TRUE;
584d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
585d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
586d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
587d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
588d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
589d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
590d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
591d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
592d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
593d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // In the current implementation, the token is just the serialized interface name that
594d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // the caller expects to be invoking
595d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
596d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str != NULL) {
597d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
598d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
599d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
600d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
601d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
602d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
603d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name)
604d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
605d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
606d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
607d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    Parcel* parcel = parcelForJavaObject(env, clazz);
608d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
609d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
610d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
611d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            IPCThreadState* threadState = IPCThreadState::self();
612d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const int32_t oldPolicy = threadState->getStrictModePolicy();
613d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const bool isValid = parcel->enforceInterface(
614d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                String16(str, env->GetStringLength(name)),
615d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                threadState);
616d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
617d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (isValid) {
618d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                const int32_t newPolicy = threadState->getStrictModePolicy();
619d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (oldPolicy != newPolicy) {
620d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Need to keep the Java-level thread-local strict
621d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // mode policy in sync for the libcore
622d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // enforcements, which involves an upcall back
623d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // into Java.  (We can't modify the
624d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Parcel.enforceInterface signature, as it's
625d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // pseudo-public, and used via AIDL
626d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // auto-generation...)
627d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    set_dalvik_blockguard_policy(env, newPolicy);
628d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
629d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                return;     // everything was correct -> return silently
630d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
631d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
632d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
633d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
634d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // all error conditions wind up here
635d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jniThrowException(env, "java/lang/SecurityException",
636d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            "Binder invocation to an incorrect interface");
637d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
638d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
639d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey// ----------------------------------------------------------------------------
640d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
641d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic const JNINativeMethod gParcelMethods[] = {
642d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"dataSize",            "()I", (void*)android_os_Parcel_dataSize},
643d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"dataAvail",           "()I", (void*)android_os_Parcel_dataAvail},
644d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"dataPosition",        "()I", (void*)android_os_Parcel_dataPosition},
645d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"dataCapacity",        "()I", (void*)android_os_Parcel_dataCapacity},
646d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"setDataSize",         "(I)V", (void*)android_os_Parcel_setDataSize},
647d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"setDataPosition",     "(I)V", (void*)android_os_Parcel_setDataPosition},
648d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"setDataCapacity",     "(I)V", (void*)android_os_Parcel_setDataCapacity},
649d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"pushAllowFds",        "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
650d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"restoreAllowFds",     "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
651d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeNative",         "([BII)V", (void*)android_os_Parcel_writeNative},
652d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeInt",            "(I)V", (void*)android_os_Parcel_writeInt},
653d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeLong",           "(J)V", (void*)android_os_Parcel_writeLong},
654d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeFloat",          "(F)V", (void*)android_os_Parcel_writeFloat},
655d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeDouble",         "(D)V", (void*)android_os_Parcel_writeDouble},
656d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeString",         "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString},
657d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeStrongBinder",   "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
658d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
659d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"createByteArray",     "()[B", (void*)android_os_Parcel_createByteArray},
660d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"readInt",             "()I", (void*)android_os_Parcel_readInt},
661d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"readLong",            "()J", (void*)android_os_Parcel_readLong},
662d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"readFloat",           "()F", (void*)android_os_Parcel_readFloat},
663d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"readDouble",          "()D", (void*)android_os_Parcel_readDouble},
664d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"readString",          "()Ljava/lang/String;", (void*)android_os_Parcel_readString},
665d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"readStrongBinder",    "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
666d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"internalReadFileDescriptor",  "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
667d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"openFileDescriptor",  "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
668d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"dupFileDescriptor",   "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
669d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
670d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
671d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"freeBuffer",          "()V", (void*)android_os_Parcel_freeBuffer},
672d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"init",                "(I)V", (void*)android_os_Parcel_init},
673d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"destroy",             "()V", (void*)android_os_Parcel_destroy},
674d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"marshall",            "()[B", (void*)android_os_Parcel_marshall},
675d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"unmarshall",          "([BII)V", (void*)android_os_Parcel_unmarshall},
676d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"appendFrom",          "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom},
677d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"hasFileDescriptors",  "()Z", (void*)android_os_Parcel_hasFileDescriptors},
678d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
679d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {"enforceInterface",    "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
680d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
681d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
682d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyconst char* const kParcelPathName = "android/os/Parcel";
683d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
684d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyint register_android_os_Parcel(JNIEnv* env)
685d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
686d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jclass clazz;
687d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
688d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    clazz = env->FindClass(kParcelPathName);
689d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
690d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
691d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    gParcelOffsets.mObject
692d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        = env->GetFieldID(clazz, "mObject", "I");
693d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    gParcelOffsets.mOwnObject
694d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        = env->GetFieldID(clazz, "mOwnObject", "I");
695d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
696d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return AndroidRuntime::registerNativeMethods(
697d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env, kParcelPathName,
698d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        gParcelMethods, NELEM(gParcelMethods));
699d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
700d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
701d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
702