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
232279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/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 <binder/IInterface.h>
32d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <binder/IPCThreadState.h>
33fb7952f57e07c68cc66a3ec69f86694057f89defSteven Moreland#include <cutils/atomic.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
442279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedUtfChars.h>
452279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedLocalRef.h>
46d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
47d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include <android_runtime/AndroidRuntime.h>
48d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
49987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h"
50987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe
51d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#undef ALOGV
52d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
53d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
54d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define DEBUG_DEATH 0
55d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#if DEBUG_DEATH
56d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOGDEATH ALOGD
57d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#else
58d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#define LOGDEATH ALOGV
59d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#endif
60d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
61d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeynamespace android {
62d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
63d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic struct parcel_offsets_t
64d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
658902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jclass clazz;
66047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    jfieldID mNativePtr;
678902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jmethodID obtain;
688902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    jmethodID recycle;
69d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey} gParcelOffsets;
70d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
71d84e1ce0b535128f03416145554fb405f9fade3eJeff SharkeyParcel* parcelForJavaObject(JNIEnv* env, jobject obj)
72d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
73d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (obj) {
748ab665dda40ab10e60fc69392022171f454af530Ashok Bhat        Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
75d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (p != NULL) {
76d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            return p;
77d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
78d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
79d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
80d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
81d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
82d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
838902097bb686752ff207e3bda12713be1a8c74ebInsun Kangjobject createJavaParcelObject(JNIEnv* env)
848902097bb686752ff207e3bda12713be1a8c74ebInsun Kang{
858902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain);
868902097bb686752ff207e3bda12713be1a8c74ebInsun Kang}
878902097bb686752ff207e3bda12713be1a8c74ebInsun Kang
888902097bb686752ff207e3bda12713be1a8c74ebInsun Kangvoid recycleJavaParcelObject(JNIEnv* env, jobject parcelObj)
898902097bb686752ff207e3bda12713be1a8c74ebInsun Kang{
908902097bb686752ff207e3bda12713be1a8c74ebInsun Kang    env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
918902097bb686752ff207e3bda12713be1a8c74ebInsun Kang}
928902097bb686752ff207e3bda12713be1a8c74ebInsun Kang
93b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jint android_os_Parcel_dataSize(jlong nativePtr)
94d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
95047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
96d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataSize() : 0;
97d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
98d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
99b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jint android_os_Parcel_dataAvail(jlong nativePtr)
100d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
101047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
102d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataAvail() : 0;
103d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
104d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
105b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jint android_os_Parcel_dataPosition(jlong nativePtr)
106d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
107047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
108d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataPosition() : 0;
109d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
110d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
111b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jint android_os_Parcel_dataCapacity(jlong nativePtr)
112d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
113047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
114d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return parcel ? parcel->dataCapacity() : 0;
115d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
116d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1170450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roosstatic jlong android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
118d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
119047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
120d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
121d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataSize(size);
122138bebf4c18d0b573732aac6faa4573a57c295f5Michael Wachenschwanz        if (err != NO_ERROR) {
123d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
124d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
1250450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos        return parcel->getOpenAshmemSize();
126d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
1270450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    return 0;
128d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
129d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
130b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic void android_os_Parcel_setDataPosition(jlong nativePtr, jint pos)
131d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
132047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
133d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
134d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(pos);
135d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
136d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
137d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1388ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
139d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
140047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
141d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
142d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->setDataCapacity(size);
143d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
144d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
145d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
146d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
147d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
148d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
149b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jboolean android_os_Parcel_pushAllowFds(jlong nativePtr, jboolean allowFds)
150d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
151047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
152d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_TRUE;
153d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
154d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        ret = (jboolean)parcel->pushAllowFds(allowFds);
155d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
156d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
157d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
158d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
159b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic void android_os_Parcel_restoreAllowFds(jlong nativePtr, jboolean lastValue)
160d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
161047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
162d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
163d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->restoreAllowFds((bool)lastValue);
164d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
165d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
166d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
1674610044cb970d25548307b9f28f79b537c15ecebJocelyn Dangstatic void android_os_Parcel_writeByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
1684610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang                                             jobject data, jint offset, jint length)
169d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
170047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
171d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
172d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
173d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
174d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
175d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    const status_t err = parcel->writeInt32(length);
176d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
177d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
178d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
179d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
180d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
181d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    void* dest = parcel->writeInplace(length);
182d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (dest == NULL) {
183d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, NO_MEMORY);
184d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
185d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
186d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
187d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
188d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ar) {
189d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(dest, ar + offset, length);
190d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
191d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
192d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
193d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
19490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddharthastatic void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
19590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                                        jint offset, jint length) {
19690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
19790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (parcel == NULL) {
19890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        return;
19990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
20090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
20139c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha    if (data == NULL) {
20239c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        const status_t err = parcel->writeInt32(-1);
20339c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        if (err != NO_ERROR) {
20439c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha            signalExceptionForError(env, clazz, err);
20539c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        }
20639c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha        return;
20739c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha    }
20839c12fab49075b715c253c68c84b5c10c3150197Sandeep Siddhartha
20990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    const status_t err = parcel->writeInt32(length);
21090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (err != NO_ERROR) {
21190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        signalExceptionForError(env, clazz, err);
21290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        return;
21390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
21490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
21590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    android::Parcel::WritableBlob blob;
216a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown    android::status_t err2 = parcel->writeBlob(length, false, &blob);
21790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (err2 != NO_ERROR) {
21890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        signalExceptionForError(env, clazz, err2);
21990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        return;
22090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
22190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
22290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
22390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (ar == NULL) {
22490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        memset(blob.data(), 0, length);
22590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    } else {
22690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        memcpy(blob.data(), ar + offset, length);
22790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
22890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
22990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
23090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    blob.release();
23190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha}
23290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
2338ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
234047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
235849ea026824d51761591a18cf6689d755f70bda4Brian Carlstrom    if (parcel != NULL) {
236849ea026824d51761591a18cf6689d755f70bda4Brian Carlstrom        const status_t err = parcel->writeInt32(val);
237849ea026824d51761591a18cf6689d755f70bda4Brian Carlstrom        if (err != NO_ERROR) {
238849ea026824d51761591a18cf6689d755f70bda4Brian Carlstrom            signalExceptionForError(env, clazz, err);
239849ea026824d51761591a18cf6689d755f70bda4Brian Carlstrom        }
240d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
241d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
242d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2438ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jlong nativePtr, jlong val)
244d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
245047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
246d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
247d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeInt64(val);
248d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
249d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
250d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
251d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
252d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
253d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2548ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jlong nativePtr, jfloat val)
255d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
256047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
257d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
258d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeFloat(val);
259d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
260d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
261d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
262d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
263d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
264d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2658ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativePtr, jdouble val)
266d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
267047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
268d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
269d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeDouble(val);
270d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
271d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
272d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
273d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
274d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
275d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2768ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
277d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
278047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
279d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
280d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        status_t err = NO_MEMORY;
281d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (val) {
282d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const jchar* str = env->GetStringCritical(val, 0);
283d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (str) {
2846698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                err = parcel->writeString16(
2856698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                    reinterpret_cast<const char16_t*>(str),
2866698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                    env->GetStringLength(val));
287d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                env->ReleaseStringCritical(val, str);
288d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
289d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        } else {
290d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            err = parcel->writeString16(NULL, 0);
291d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
292d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
293d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
294d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
295d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
296d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
297d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
2988ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
299d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
300047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
301d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
302d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
303d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
304d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
305d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
306d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
307d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
308d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3090450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roosstatic jlong android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
310d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
311047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
312d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
313d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const status_t err =
314d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
315d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (err != NO_ERROR) {
316d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            signalExceptionForError(env, clazz, err);
317d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
3180450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos        return parcel->getOpenAshmemSize();
319d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
3200450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    return 0;
321d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
322d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3238ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr)
324d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
325d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = NULL;
326d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
327047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
328d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
329d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int32_t len = parcel->readInt32();
330d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
331d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // sanity check the stored length against the true data size
332d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
333d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = env->NewByteArray(len);
334d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
335d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (ret != NULL) {
336d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
337d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (a2) {
338d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    const void* data = parcel->readInplace(len);
339d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    memcpy(a2, data, len);
340d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
341d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
342d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
343d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
344d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
345d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
346d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
347d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
348d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
3494610044cb970d25548307b9f28f79b537c15ecebJocelyn Dangstatic jboolean android_os_Parcel_readByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
3504610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang                                                jobject dest, jint destLen)
3514610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang{
3524610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    jboolean ret = JNI_FALSE;
3534610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
3544610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    if (parcel == NULL) {
3554610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang        return ret;
3564610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    }
3574610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang
3584610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    int32_t len = parcel->readInt32();
3594610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    if (len >= 0 && len <= (int32_t)parcel->dataAvail() && len == destLen) {
3604610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang        jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)dest, 0);
3614610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang        if (ar) {
3624610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang            const void* data = parcel->readInplace(len);
3634610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang            memcpy(ar, data, len);
3644610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang            env->ReleasePrimitiveArrayCritical((jarray)dest, ar, 0);
3654610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang            ret = JNI_TRUE;
3664610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang        }
3674610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    }
3684610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    return ret;
3694610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang}
3704610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang
37190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddharthastatic jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
37290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha{
37390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    jbyteArray ret = NULL;
37490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
37590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
37690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    if (parcel != NULL) {
37790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        int32_t len = parcel->readInt32();
37890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        if (len >= 0) {
37990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            android::Parcel::ReadableBlob blob;
38090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            android::status_t err = parcel->readBlob(len, &blob);
38190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            if (err != NO_ERROR) {
38290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                signalExceptionForError(env, clazz, err);
38390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                return NULL;
38490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            }
38590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
38690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            ret = env->NewByteArray(len);
38790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            if (ret != NULL) {
38890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
38990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                if (a2) {
39090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                    memcpy(a2, blob.data(), len);
39190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
39290d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha                }
39390d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            }
39490d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha            blob.release();
39590d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha        }
39690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    }
39790d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
39890d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    return ret;
39990d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha}
40090d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha
401b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jint android_os_Parcel_readInt(jlong nativePtr)
402d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
403047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
404d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
405d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt32();
406d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
407d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
408d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
409d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
410b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jlong android_os_Parcel_readLong(jlong nativePtr)
411d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
412047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
413d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
414d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readInt64();
415d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
416d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
417d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
418d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
419b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jfloat android_os_Parcel_readFloat(jlong nativePtr)
420d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
421047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
422d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
423d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readFloat();
424d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
425d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
426d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
427d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
428b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jdouble android_os_Parcel_readDouble(jlong nativePtr)
429d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
430047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
431d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
432d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return parcel->readDouble();
433d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
434d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return 0;
435d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
436d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
4378ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr)
438d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
439047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
440d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
441d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        size_t len;
442d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const char16_t* str = parcel->readString16Inplace(&len);
443d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
4446698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert            return env->NewString(reinterpret_cast<const jchar*>(str), len);
445d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
446d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
447d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
448d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
449d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
450d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
4518ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
452d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
453047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
454d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
455d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return javaObjectForIBinder(env, parcel->readStrongBinder());
456d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
457d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
458d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
459d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
4608ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr)
461d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
462047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
463d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
464d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        int fd = parcel->readFileDescriptor();
465d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
466d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        fd = dup(fd);
467d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (fd < 0) return NULL;
468d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return jniCreateFileDescriptor(env, fd);
469d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
470d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return NULL;
471d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
472d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
473047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
474d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                                                    jstring name, jint mode)
475d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
476d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (name == NULL) {
477d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
478d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
479d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
480d415303c4d02c1d30dd4199bade4694bf2cb4615tao.pei    ScopedUtfChars name8(env, name);
481d415303c4d02c1d30dd4199bade4694bf2cb4615tao.pei    if (name8.c_str() == NULL) {
482d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
483d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
484d415303c4d02c1d30dd4199bade4694bf2cb4615tao.pei
485d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int flags=0;
486d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    switch (mode&0x30000000) {
487d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0:
488d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x10000000:
489d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDONLY;
490d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
491d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x20000000:
492d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_WRONLY;
493d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
494d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        case 0x30000000:
495d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            flags = O_RDWR;
496d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            break;
497d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
498d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
499d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x08000000) flags |= O_CREAT;
500d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x04000000) flags |= O_TRUNC;
501d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x02000000) flags |= O_APPEND;
502d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
503d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int realMode = S_IRWXU|S_IRWXG;
504d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000001) realMode |= S_IROTH;
505d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (mode&0x00000002) realMode |= S_IWOTH;
506d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
507d415303c4d02c1d30dd4199bade4694bf2cb4615tao.pei    int fd = open(name8.c_str(), flags, realMode);
508d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
509d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
510d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
511d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
512d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
513d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
514d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
515d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
516d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
517d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
518d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
519047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
520d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
521d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (orig == NULL) {
522d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
523d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
524d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
525d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int origfd = jniGetFDFromFileDescriptor(env, orig);
526d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (origfd < 0) {
527d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
528d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
529d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
530d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
531d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = dup(origfd);
532d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd < 0) {
533d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowIOException(env, errno);
534d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
535d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
536d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jobject object = jniCreateFileDescriptor(env, fd);
537d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
538d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
539d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
540d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return object;
541d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
542d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
543047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkeystatic void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
544d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
545d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (object == NULL) {
546d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowNullPointerException(env, NULL);
547d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return;
548d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
549d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    int fd = jniGetFDFromFileDescriptor(env, object);
550d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (fd >= 0) {
551d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniSetFileDescriptorOfFD(env, object, -1);
552d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
553d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        close(fd);
554d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
555d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
556d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5578ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
558d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
559047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = new Parcel();
5608ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    return reinterpret_cast<jlong>(parcel);
561d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
562d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5630450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roosstatic jlong android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
564d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
565047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
566047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    if (parcel != NULL) {
567047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey        parcel->freeData();
5680450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos        return parcel->getOpenAshmemSize();
569d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
5700450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    return 0;
571d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
572d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5738ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr)
574d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
575047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
576047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    delete parcel;
577d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
578d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
5798ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
580d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
581047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
582d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL) {
583d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey       return NULL;
584d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
585d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
586d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // do not marshall if there are binder objects in the parcel
587d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel->objectsCount())
588d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
589d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
590d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        return NULL;
591d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
592d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
593d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyteArray ret = env->NewByteArray(parcel->dataSize());
594d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
595d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (ret != NULL)
596d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
597d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
598d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (array != NULL)
599d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        {
600d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            memcpy(array, parcel->data(), parcel->dataSize());
601d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleasePrimitiveArrayCritical(ret, array, 0);
602d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
603d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
604d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
605d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
606d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
607d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6080450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roosstatic jlong android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
6090450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos                                          jbyteArray data, jint offset, jint length)
610d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
611047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
612d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel == NULL || length < 0) {
6130450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos       return 0;
614d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
615d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
616d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
617d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (array)
618d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    {
619d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataSize(length);
620d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        parcel->setDataPosition(0);
621d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
622d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        void* raw = parcel->writeInplace(length);
623d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        memcpy(raw, (array + offset), length);
624d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
625d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        env->ReleasePrimitiveArrayCritical(data, array, 0);
626d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
6270450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    return parcel->getOpenAshmemSize();
628d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
629d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6307da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackbornstatic jint android_os_Parcel_compareData(JNIEnv* env, jclass clazz, jlong thisNativePtr,
6317da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn                                          jlong otherNativePtr)
6327da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn{
6337da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
6347da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    if (thisParcel == NULL) {
6357da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn       return 0;
6367da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    }
6377da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
6387da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    if (otherParcel == NULL) {
6397da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn       return thisParcel->getOpenAshmemSize();
6407da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    }
6417da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn
6427da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    return thisParcel->compareData(*otherParcel);
6437da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn}
6447da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn
6450450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roosstatic jlong android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
6460450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos                                          jlong otherNativePtr, jint offset, jint length)
647d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
648047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
649d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (thisParcel == NULL) {
6500450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos       return 0;
651d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
652047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
653d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (otherParcel == NULL) {
6540450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos       return thisParcel->getOpenAshmemSize();
655d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
656d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
657d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    status_t err = thisParcel->appendFrom(otherParcel, offset, length);
658d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (err != NO_ERROR) {
659d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        signalExceptionForError(env, clazz, err);
660d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
6610450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    return thisParcel->getOpenAshmemSize();
662d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
663d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
664b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr)
665d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
666d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jboolean ret = JNI_FALSE;
667047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
668d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
669d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (parcel->hasFileDescriptors()) {
670d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            ret = JNI_TRUE;
671d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
672d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
673d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    return ret;
674d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
675d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6768ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr,
677047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey                                                  jstring name)
678d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
679047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
680d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
681d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // In the current implementation, the token is just the serialized interface name that
682d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        // the caller expects to be invoking
683d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
684d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str != NULL) {
6856698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert            parcel->writeInterfaceToken(String16(
6866698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                  reinterpret_cast<const char16_t*>(str),
6876698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                  env->GetStringLength(name)));
688d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
689d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
690d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
691d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
692d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
6938ab665dda40ab10e60fc69392022171f454af530Ashok Bhatstatic void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
694d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
695047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
696d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    if (parcel != NULL) {
697d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        const jchar* str = env->GetStringCritical(name, 0);
698d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        if (str) {
699d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            IPCThreadState* threadState = IPCThreadState::self();
700d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const int32_t oldPolicy = threadState->getStrictModePolicy();
701d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            const bool isValid = parcel->enforceInterface(
7026698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                String16(reinterpret_cast<const char16_t*>(str),
7036698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                         env->GetStringLength(name)),
704d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                threadState);
705d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            env->ReleaseStringCritical(name, str);
706d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            if (isValid) {
707d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                const int32_t newPolicy = threadState->getStrictModePolicy();
708d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                if (oldPolicy != newPolicy) {
709d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Need to keep the Java-level thread-local strict
710d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // mode policy in sync for the libcore
711d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // enforcements, which involves an upcall back
712d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // into Java.  (We can't modify the
713d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // Parcel.enforceInterface signature, as it's
714d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // pseudo-public, and used via AIDL
715d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    // auto-generation...)
716d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                    set_dalvik_blockguard_policy(env, newPolicy);
717d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                }
718d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey                return;     // everything was correct -> return silently
719d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            }
720d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey        }
721d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    }
722d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
723d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    // all error conditions wind up here
724d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey    jniThrowException(env, "java/lang/SecurityException",
725d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey            "Binder invocation to an incorrect interface");
726d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
727d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
728fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackbornstatic jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz)
729fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn{
730fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn    return Parcel::getGlobalAllocSize();
731fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn}
732fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn
733fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackbornstatic jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz)
734fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn{
735fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn    return Parcel::getGlobalAllocCount();
736fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn}
737fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn
738b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onukistatic jlong android_os_Parcel_getBlobAshmemSize(jlong nativePtr)
7395ce0430edfc176de29c0cf503975570dfda8111fDan Sandler{
7405ce0430edfc176de29c0cf503975570dfda8111fDan Sandler    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
7415ce0430edfc176de29c0cf503975570dfda8111fDan Sandler    if (parcel != NULL) {
7425ce0430edfc176de29c0cf503975570dfda8111fDan Sandler        return parcel->getBlobAshmemSize();
7435ce0430edfc176de29c0cf503975570dfda8111fDan Sandler    }
7445ce0430edfc176de29c0cf503975570dfda8111fDan Sandler    return 0;
7455ce0430edfc176de29c0cf503975570dfda8111fDan Sandler}
7465ce0430edfc176de29c0cf503975570dfda8111fDan Sandler
747d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey// ----------------------------------------------------------------------------
748d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
749d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeystatic const JNINativeMethod gParcelMethods[] = {
750b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
75171207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeDataSize",            "(J)I", (void*)android_os_Parcel_dataSize},
752b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
75371207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeDataAvail",           "(J)I", (void*)android_os_Parcel_dataAvail},
754b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
75571207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeDataPosition",        "(J)I", (void*)android_os_Parcel_dataPosition},
756b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
75771207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeDataCapacity",        "(J)I", (void*)android_os_Parcel_dataCapacity},
75871207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    // @FastNative
75971207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeSetDataSize",         "(JI)J", (void*)android_os_Parcel_setDataSize},
760b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
76171207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeSetDataPosition",     "(JI)V", (void*)android_os_Parcel_setDataPosition},
76271207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    // @FastNative
76371207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeSetDataCapacity",     "(JI)V", (void*)android_os_Parcel_setDataCapacity},
76471207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck
765b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
76671207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativePushAllowFds",        "(JZ)Z", (void*)android_os_Parcel_pushAllowFds},
767b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
76871207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
7698ab665dda40ab10e60fc69392022171f454af530Ashok Bhat
7704610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeByteArray},
77190d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    {"nativeWriteBlob",           "(J[BII)V", (void*)android_os_Parcel_writeBlob},
77271207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    // @FastNative
77371207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
77471207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    // @FastNative
77571207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeWriteLong",           "(JJ)V", (void*)android_os_Parcel_writeLong},
77671207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    // @FastNative
77771207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeWriteFloat",          "(JF)V", (void*)android_os_Parcel_writeFloat},
77871207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    // @FastNative
77971207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeWriteDouble",         "(JD)V", (void*)android_os_Parcel_writeDouble},
7808ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteString",         "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
7818ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteStrongBinder",   "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
7820450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
7838ab665dda40ab10e60fc69392022171f454af530Ashok Bhat
7848ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
7854610044cb970d25548307b9f28f79b537c15ecebJocelyn Dang    {"nativeReadByteArray",       "(J[BI)Z", (void*)android_os_Parcel_readByteArray},
78690d7a3e996ee3a6e33e655341c5d301fbe30cd58Sandeep Siddhartha    {"nativeReadBlob",            "(J)[B", (void*)android_os_Parcel_readBlob},
787b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
78871207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},
789b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
79071207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeReadLong",            "(J)J", (void*)android_os_Parcel_readLong},
791b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
79271207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeReadFloat",           "(J)F", (void*)android_os_Parcel_readFloat},
793b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
79471207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeReadDouble",          "(J)D", (void*)android_os_Parcel_readDouble},
7958ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadString",          "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
7968ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
7978ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeReadFileDescriptor",  "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
798047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
799047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"openFileDescriptor",        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
800047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"dupFileDescriptor",         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
801047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey    {"closeFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
802047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
8038ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeCreate",              "()J", (void*)android_os_Parcel_create},
8040450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    {"nativeFreeBuffer",          "(J)J", (void*)android_os_Parcel_freeBuffer},
8058ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeDestroy",             "(J)V", (void*)android_os_Parcel_destroy},
806047238ced42eea812de9d39a9f32e94d002bfa5cJeff Sharkey
8078ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeMarshall",            "(J)[B", (void*)android_os_Parcel_marshall},
8080450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    {"nativeUnmarshall",          "(J[BII)J", (void*)android_os_Parcel_unmarshall},
8097da13d7c3e5b48c0410ae869c5679652de97e5aaDianne Hackborn    {"nativeCompareData",         "(JJ)I", (void*)android_os_Parcel_compareData},
8100450565d9a6de0f0828c9ad8ce16c8645c6f394cAdrian Roos    {"nativeAppendFrom",          "(JJII)J", (void*)android_os_Parcel_appendFrom},
811b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
81271207b5a11c1aaede2ccc2380a9c55b6ff0162d3John Reck    {"nativeHasFileDescriptors",  "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
8138ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
8148ab665dda40ab10e60fc69392022171f454af530Ashok Bhat    {"nativeEnforceInterface",    "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
815fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn
816fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn    {"getGlobalAllocSize",        "()J", (void*)android_os_Parcel_getGlobalAllocSize},
817fabb70b2efbd125f74923d19ab12bc8e1371ed1fDianne Hackborn    {"getGlobalAllocCount",       "()J", (void*)android_os_Parcel_getGlobalAllocCount},
8185ce0430edfc176de29c0cf503975570dfda8111fDan Sandler
819b148b6c3c8547143946726a4f6143106406f2fd2Makoto Onuki    // @CriticalNative
820aa861666ed537389e335f586bc84fe8ddb9fb026Dan Sandler    {"nativeGetBlobAshmemSize",       "(J)J", (void*)android_os_Parcel_getBlobAshmemSize},
821d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
822d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
823d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyconst char* const kParcelPathName = "android/os/Parcel";
824d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
825d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkeyint register_android_os_Parcel(JNIEnv* env)
826d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey{
827987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    jclass clazz = FindClassOrDie(env, kParcelPathName);
828d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
829987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gParcelOffsets.clazz = MakeGlobalRefOrDie(env, clazz);
830987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gParcelOffsets.mNativePtr = GetFieldIDOrDie(env, clazz, "mNativePtr", "J");
831987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gParcelOffsets.obtain = GetStaticMethodIDOrDie(env, clazz, "obtain", "()Landroid/os/Parcel;");
832987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gParcelOffsets.recycle = GetMethodIDOrDie(env, clazz, "recycle", "()V");
833d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
834987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    return RegisterMethodsOrDie(env, kParcelPathName, gParcelMethods, NELEM(gParcelMethods));
835d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey}
836d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey
837d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey};
838