android_os_Parcel.cpp revision 39c12fab49075b715c253c68c84b5c10c3150197
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 <binder/Parcel.h>
39d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/ProcessState.h>
40d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/IServiceManager.h>
41d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/threads.h>
42d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <utils/String8.h>
43d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
44d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <ScopedUtfChars.h>
45d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <ScopedLocalRef.h>
46d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
47d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <android_runtime/AndroidRuntime.h>
48d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
49d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#undef ALOGV
50d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
51d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
52d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define DEBUG_DEATH 0
53d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#if DEBUG_DEATH
54d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOGDEATH ALOGD
55d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#else
56d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOGDEATH ALOGV
57d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#endif
58d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
59d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeynamespace android {
60d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
61d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic struct parcel_offsets_t
62d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
638902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jclass clazz;
64047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    jfieldID mNativePtr;
658902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jmethodID obtain;
668902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jmethodID recycle;
67d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey} gParcelOffsets;
68d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
69d84e1ce0b535128f03416145554fb405f9fade3eJeff SharkeyParcel* parcelForJavaObject(JNIEnv* env, jobject obj)
70d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
71d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (obj) {
728ab665dda40ab10e60fc69392022171f454af530Ashok Bhat        Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
73d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (p != NULL) {
74d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return p;
75d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
76d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
77d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
78d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
79d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
80d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
818902097bb686752ff207e3bda12713be1a8c74ebInsun Kangjobject createJavaParcelObject(JNIEnv* env)
828902097bb686752ff207e3bda12713be1a8c74ebInsun Kang{
838902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain);
848902097bb686752ff207e3bda12713be1a8c74ebInsun Kang}
858902097bb686752ff207e3bda12713be1a8c74ebInsun Kang
868902097bb686752ff207e3bda12713be1a8c74ebInsun Kangvoid recycleJavaParcelObject(JNIEnv* env, jobject parcelObj)
878902097bb686752ff207e3bda12713be1a8c74ebInsun Kang{
888902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
898902097bb686752ff207e3bda12713be1a8c74ebInsun Kang}
908902097bb686752ff207e3bda12713be1a8c74ebInsun Kang
918ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jlong nativePtr)
92d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
93047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
94d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataSize() : 0;
95d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
96d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
978ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jlong nativePtr)
98d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
99047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
100d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataAvail() : 0;
101d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
102d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1038ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jlong nativePtr)
104d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
105047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
106d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataPosition() : 0;
107d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
108d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1098ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr)
110d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
111047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
112d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataCapacity() : 0;
113d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
114d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1158ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
116d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
117047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
118d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
119d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataSize(size);
120d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
121d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
122d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
123d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
124d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
125d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1268ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jlong nativePtr, jint pos)
127d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
128047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
129d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
130d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(pos);
131d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
132d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
133d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1348ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
135d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
136047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
137d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
138d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataCapacity(size);
139d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
140d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
141d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
142d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
143d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
144d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1458ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean allowFds)
146d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
147047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
148d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_TRUE;
149d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
150d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        ret = (jboolean)parcel->pushAllowFds(allowFds);
151d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
152d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
153d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
154d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1558ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean lastValue)
156d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
157047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
158d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
159d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->restoreAllowFds((bool)lastValue);
160d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
161d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
162d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1638ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
164047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                          jint offset, jint length)
165d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
166047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
167d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
168d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
169d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
170d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
171d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const status_t err = parcel->writeInt32(length);
172d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
173d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
174d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
175d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
176d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
177d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    void* dest = parcel->writeInplace(length);
178d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (dest == NULL) {
179d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, NO_MEMORY);
180d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
181d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
182d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
183d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
184d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ar) {
185d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(dest, ar + offset, length);
186d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
187d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
188d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
189d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
19090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddharthastatic void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
19190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                                        jint offset, jint length) {
19290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
19390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (parcel == NULL) {
19490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        return;
19590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
19690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
19739c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha    if (data == NULL) {
19839c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        const status_t err = parcel->writeInt32(-1);
19939c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        if (err != NO_ERROR) {
20039c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha            signalExceptionForError(env, clazz, err);
20139c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        }
20239c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        return;
20339c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha    }
20439c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha
20590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    const status_t err = parcel->writeInt32(length);
20690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (err != NO_ERROR) {
20790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        signalExceptionForError(env, clazz, err);
20890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        return;
20990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
21090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
21190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    android::Parcel::WritableBlob blob;
21290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    android::status_t err2 = parcel->writeBlob(length, &blob);
21390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (err2 != NO_ERROR) {
21490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        signalExceptionForError(env, clazz, err2);
21590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        return;
21690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
21790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
21890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
21990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (ar == NULL) {
22090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        memset(blob.data(), 0, length);
22190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    } else {
22290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        memcpy(blob.data(), ar + offset, length);
22390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
22490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
22590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
22690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    blob.release();
22790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha}
22890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
2298ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
230047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
231047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    const status_t err = parcel->writeInt32(val);
232047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    if (err != NO_ERROR) {
233047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey        signalExceptionForError(env, clazz, err);
234d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
235d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
236d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2378ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jlong nativePtr, jlong val)
238d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
239047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
240d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
241d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeInt64(val);
242d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
243d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
244d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
245d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
246d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
247d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2488ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jlong nativePtr, jfloat val)
249d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
250047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
251d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
252d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeFloat(val);
253d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
254d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
255d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
256d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
257d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
258d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2598ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativePtr, jdouble val)
260d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
261047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
262d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
263d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeDouble(val);
264d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
265d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
266d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
267d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
268d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
269d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2708ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
271d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
272047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
273d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
274d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        status_t err = NO_MEMORY;
275d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (val) {
276d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const jchar* str = env->GetStringCritical(val, 0);
277d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (str) {
278d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                err = parcel->writeString16(str, env->GetStringLength(val));
279d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                env->ReleaseStringCritical(val, str);
280d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
281d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        } else {
282d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            err = parcel->writeString16(NULL, 0);
283d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
284d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
285d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
286d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
287d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
288d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
289d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2908ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
291d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
292047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
293d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
294d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
295d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
296d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
297d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
298d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
299d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
300d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3018ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
302d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
303047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
304d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
305d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err =
306d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
307d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
308d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
309d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
310d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
311d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
312d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3138ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr)
314d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
315d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = NULL;
316d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
317047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
318d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
319d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int32_t len = parcel->readInt32();
320d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
321d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // sanity check the stored length against the true data size
322d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
323d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = env->NewByteArray(len);
324d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
325d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (ret != NULL) {
326d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
327d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (a2) {
328d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    const void* data = parcel->readInplace(len);
329d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    memcpy(a2, data, len);
330d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
331d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
332d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
333d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
334d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
335d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
336d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
337d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
338d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
33990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddharthastatic jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
34090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha{
34190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    jbyteArray ret = NULL;
34290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
34390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
34490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (parcel != NULL) {
34590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        int32_t len = parcel->readInt32();
34690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        if (len >= 0) {
34790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            android::Parcel::ReadableBlob blob;
34890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            android::status_t err = parcel->readBlob(len, &blob);
34990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            if (err != NO_ERROR) {
35090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                signalExceptionForError(env, clazz, err);
35190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                return NULL;
35290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            }
35390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
35490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            ret = env->NewByteArray(len);
35590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            if (ret != NULL) {
35690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
35790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                if (a2) {
35890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                    memcpy(a2, blob.data(), len);
35990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
36090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                }
36190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            }
36290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            blob.release();
36390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        }
36490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
36590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
36690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    return ret;
36790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha}
36890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
3698ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jlong nativePtr)
370d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
371047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
372d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
373d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt32();
374d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
375d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
376d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
377d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3788ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jlong nativePtr)
379d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
380047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
381d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
382d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt64();
383d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
384d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
385d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
386d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3878ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jlong nativePtr)
388d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
389047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
390d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
391d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readFloat();
392d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
393d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
394d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
395d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3968ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jlong nativePtr)
397d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
398047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
399d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
400d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readDouble();
401d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
402d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
403d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
404d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
4058ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr)
406d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
407047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
408d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
409d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        size_t len;
410d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const char16_t* str = parcel->readString16Inplace(&len);
411d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
412d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return env->NewString(str, len);
413d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
414d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
415d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
416d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
417d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
418d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
4198ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
420d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
421047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
422d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
423d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return javaObjectForIBinder(env, parcel->readStrongBinder());
424d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
425d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
426d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
427d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
4288ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr)
429d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
430047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
431d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
432d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int fd = parcel->readFileDescriptor();
433d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
434d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        fd = dup(fd);
435d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
436d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return jniCreateFileDescriptor(env, fd);
437d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
438d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
439d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
440d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
441047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
442d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                                                    jstring name, jint mode)
443d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
444d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (name == NULL) {
445d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
446d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
447d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
448d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const jchar* str = env->GetStringCritical(name, 0);
449d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (str == NULL) {
450d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // Whatever, whatever.
451d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", NULL);
452d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
453d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
454d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    String8 name8(str, env->GetStringLength(name));
455d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    env->ReleaseStringCritical(name, str);
456d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int flags=0;
457d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    switch (mode&0x30000000) {
458d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0:
459d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x10000000:
460d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDONLY;
461d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
462d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x20000000:
463d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_WRONLY;
464d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
465d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x30000000:
466d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDWR;
467d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
468d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
469d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
470d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x08000000) flags |= O_CREAT;
471d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x04000000) flags |= O_TRUNC;
472d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x02000000) flags |= O_APPEND;
473d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
474d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int realMode = S_IRWXU|S_IRWXG;
475d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000001) realMode |= S_IROTH;
476d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000002) realMode |= S_IWOTH;
477d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
478d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = open(name8.string(), flags, realMode);
479d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
480d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
481d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
482d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
483d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
484d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
485d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
486d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
487d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
488d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
489d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
490047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
491d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
492d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (orig == NULL) {
493d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
494d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
495d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
496d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int origfd = jniGetFDFromFileDescriptor(env, orig);
497d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (origfd < 0) {
498d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
499d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
500d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
501d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
502d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = dup(origfd);
503d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
504d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowIOException(env, errno);
505d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
506d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
507d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
508d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
509d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
510d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
511d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
512d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
513d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
514047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
515d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
516d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
517d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
518d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
519d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
520d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
521d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
522d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
523d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
524d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
525d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
526d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
527d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
528047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
529d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
530d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
531d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
532d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
533d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
534d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
535d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
536d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
537d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
538d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
539d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5408ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
541d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
542047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = new Parcel();
5438ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    return reinterpret_cast<jlong>(parcel);
544d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
545d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5468ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
547d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
548047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
549047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    if (parcel != NULL) {
550047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey        parcel->freeData();
551d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
552d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
553d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5548ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr)
555d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
556047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
557047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    delete parcel;
558d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
559d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5608ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
561d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
562047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
563d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
564d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return NULL;
565d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
566d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
567d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // do not marshall if there are binder objects in the parcel
568d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel->objectsCount())
569d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
570d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
571d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
572d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
573d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
574d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = env->NewByteArray(parcel->dataSize());
575d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
576d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ret != NULL)
577d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
578d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
579d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (array != NULL)
580d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        {
581d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            memcpy(array, parcel->data(), parcel->dataSize());
582d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleasePrimitiveArrayCritical(ret, array, 0);
583d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
584d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
585d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
586d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
587d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
588d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5898ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
590047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                         jbyteArray data, jint offset, jint length)
591d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
592047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
593d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL || length < 0) {
594d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
595d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
596d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
597d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
598d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (array)
599d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
600d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataSize(length);
601d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(0);
602d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
603d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        void* raw = parcel->writeInplace(length);
604d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(raw, (array + offset), length);
605d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
606d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical(data, array, 0);
607d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
608d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
609d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6108ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
6118ab665dda40ab10e60fc69392022171f454af530Ashok Bhat                                         jlong otherNativePtr, jint offset, jint length)
612d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
613047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
614d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (thisParcel == NULL) {
615d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
616d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
617047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
618d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (otherParcel == NULL) {
619d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return;
620d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
621d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
622d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    status_t err = thisParcel->appendFrom(otherParcel, offset, length);
623d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
624d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
625d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
626d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
627d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6288ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jlong nativePtr)
629d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
630d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
631047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
632d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
633d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (parcel->hasFileDescriptors()) {
634d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = JNI_TRUE;
635d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
636d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
637d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
638d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
639d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6408ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr,
641047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                                  jstring name)
642d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
643047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
644d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
645d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // In the current implementation, the token is just the serialized interface name that
646d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // the caller expects to be invoking
647d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
648d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str != NULL) {
649d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
650d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
651d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
652d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
653d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
654d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6558ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
656d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
657d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
658d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
659047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
660d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
661d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
662d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
663d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            IPCThreadState* threadState = IPCThreadState::self();
664d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const int32_t oldPolicy = threadState->getStrictModePolicy();
665d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const bool isValid = parcel->enforceInterface(
666d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                String16(str, env->GetStringLength(name)),
667d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                threadState);
668d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
669d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (isValid) {
670d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                const int32_t newPolicy = threadState->getStrictModePolicy();
671d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (oldPolicy != newPolicy) {
672d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Need to keep the Java-level thread-local strict
673d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // mode policy in sync for the libcore
674d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // enforcements, which involves an upcall back
675d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // into Java.  (We can't modify the
676d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Parcel.enforceInterface signature, as it's
677d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // pseudo-public, and used via AIDL
678d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // auto-generation...)
679d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    set_dalvik_blockguard_policy(env, newPolicy);
680d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
681d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                return;     // everything was correct -> return silently
682d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
683d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
684d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
685d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
686d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // all error conditions wind up here
687d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jniThrowException(env, "java/lang/SecurityException",
688d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            "Binder invocation to an incorrect interface");
689d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
690d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
691d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey// ----------------------------------------------------------------------------
692d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
693d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic const JNINativeMethod gParcelMethods[] = {
6948ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeDataSize",            "(J)I", (void*)android_os_Parcel_dataSize},
6958ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeDataAvail",           "(J)I", (void*)android_os_Parcel_dataAvail},
6968ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeDataPosition",        "(J)I", (void*)android_os_Parcel_dataPosition},
6978ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeDataCapacity",        "(J)I", (void*)android_os_Parcel_dataCapacity},
6988ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeSetDataSize",         "(JI)V", (void*)android_os_Parcel_setDataSize},
6998ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeSetDataPosition",     "(JI)V", (void*)android_os_Parcel_setDataPosition},
7008ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeSetDataCapacity",     "(JI)V", (void*)android_os_Parcel_setDataCapacity},
7018ab665dda40ab10e60fc69392022171f454af530Ashok Bhat
7028ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativePushAllowFds",        "(JZ)Z", (void*)android_os_Parcel_pushAllowFds},
7038ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
7048ab665dda40ab10e60fc69392022171f454af530Ashok Bhat
7058ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeNative},
70690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    {"nativeWriteBlob",           "(J[BII)V", (void*)android_os_Parcel_writeBlob},
7078ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
7088ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteLong",           "(JJ)V", (void*)android_os_Parcel_writeLong},
7098ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteFloat",          "(JF)V", (void*)android_os_Parcel_writeFloat},
7108ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteDouble",         "(JD)V", (void*)android_os_Parcel_writeDouble},
7118ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteString",         "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
7128ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteStrongBinder",   "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
7138ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
7148ab665dda40ab10e60fc69392022171f454af530Ashok Bhat
7158ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
71690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    {"nativeReadBlob",            "(J)[B", (void*)android_os_Parcel_readBlob},
7178ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},
7188ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadLong",            "(J)J", (void*)android_os_Parcel_readLong},
7198ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadFloat",           "(J)F", (void*)android_os_Parcel_readFloat},
7208ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadDouble",          "(J)D", (void*)android_os_Parcel_readDouble},
7218ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadString",          "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
7228ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
7238ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadFileDescriptor",  "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
724047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
725047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"openFileDescriptor",        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
726047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"dupFileDescriptor",         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
727047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"closeFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
728047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"clearFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
729047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
7308ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeCreate",              "()J", (void*)android_os_Parcel_create},
7318ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeFreeBuffer",          "(J)V", (void*)android_os_Parcel_freeBuffer},
7328ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeDestroy",             "(J)V", (void*)android_os_Parcel_destroy},
733047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
7348ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeMarshall",            "(J)[B", (void*)android_os_Parcel_marshall},
7358ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeUnmarshall",          "(J[BII)V", (void*)android_os_Parcel_unmarshall},
7368ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeAppendFrom",          "(JJII)V", (void*)android_os_Parcel_appendFrom},
7378ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeHasFileDescriptors",  "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
7388ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
7398ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeEnforceInterface",    "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
740d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
741d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
742d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyconst char* const kParcelPathName = "android/os/Parcel";
743d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
744d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyint register_android_os_Parcel(JNIEnv* env)
745d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
746d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jclass clazz;
747d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
748d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    clazz = env->FindClass(kParcelPathName);
749d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
750d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
7518902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.clazz = (jclass) env->NewGlobalRef(clazz);
7528ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    gParcelOffsets.mNativePtr = env->GetFieldID(clazz, "mNativePtr", "J");
7538902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.obtain = env->GetStaticMethodID(clazz, "obtain",
7548902097bb686752ff207e3bda12713be1a8c74ebInsun Kang                                                   "()Landroid/os/Parcel;");
7558902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    gParcelOffsets.recycle = env->GetMethodID(clazz, "recycle", "()V");
756d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
757d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return AndroidRuntime::registerNativeMethods(
758d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env, kParcelPathName,
759d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        gParcelMethods, NELEM(gParcelMethods));
760d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
761d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
762d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
763