blob: d80c071c3e26cca17c56e631bbba07e6c5e4a738 [file] [log] [blame]
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Parcel"
18//#define LOG_NDEBUG 0
19
20#include "android_os_Parcel.h"
21#include "android_util_Binder.h"
22
Steven Moreland2279b252017-07-19 09:50:45 -070023#include <nativehelper/JNIHelp.h>
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080024
25#include <fcntl.h>
26#include <stdio.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <unistd.h>
30
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080031#include <binder/IInterface.h>
32#include <binder/IPCThreadState.h>
Steven Morelandfb7952f2018-02-23 14:58:50 -080033#include <cutils/atomic.h>
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080034#include <utils/Log.h>
35#include <utils/SystemClock.h>
36#include <utils/List.h>
37#include <utils/KeyedVector.h>
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080038#include <binder/Parcel.h>
39#include <binder/ProcessState.h>
40#include <binder/IServiceManager.h>
41#include <utils/threads.h>
42#include <utils/String8.h>
43
Steven Moreland2279b252017-07-19 09:50:45 -070044#include <nativehelper/ScopedUtfChars.h>
45#include <nativehelper/ScopedLocalRef.h>
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080046
47#include <android_runtime/AndroidRuntime.h>
48
Andreas Gampe987f79f2014-11-18 17:29:46 -080049#include "core_jni_helpers.h"
50
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080051//#undef ALOGV
52//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
53
54#define DEBUG_DEATH 0
55#if DEBUG_DEATH
56#define LOGDEATH ALOGD
57#else
58#define LOGDEATH ALOGV
59#endif
60
61namespace android {
62
63static struct parcel_offsets_t
64{
Insun Kang89020972012-05-01 14:13:19 +090065 jclass clazz;
Jeff Sharkey047238c2012-03-07 16:51:38 -080066 jfieldID mNativePtr;
Insun Kang89020972012-05-01 14:13:19 +090067 jmethodID obtain;
68 jmethodID recycle;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080069} gParcelOffsets;
70
71Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
72{
73 if (obj) {
Ashok Bhat8ab665d2014-01-22 16:00:20 +000074 Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080075 if (p != NULL) {
76 return p;
77 }
78 jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
79 }
80 return NULL;
81}
82
Insun Kang89020972012-05-01 14:13:19 +090083jobject createJavaParcelObject(JNIEnv* env)
84{
85 return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain);
86}
87
88void recycleJavaParcelObject(JNIEnv* env, jobject parcelObj)
89{
90 env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
91}
92
Makoto Onukib148b6c2017-06-27 13:38:38 -070093static jint android_os_Parcel_dataSize(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080094{
Jeff Sharkey047238c2012-03-07 16:51:38 -080095 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080096 return parcel ? parcel->dataSize() : 0;
97}
98
Makoto Onukib148b6c2017-06-27 13:38:38 -070099static jint android_os_Parcel_dataAvail(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800100{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800101 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800102 return parcel ? parcel->dataAvail() : 0;
103}
104
Makoto Onukib148b6c2017-06-27 13:38:38 -0700105static jint android_os_Parcel_dataPosition(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800106{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800107 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800108 return parcel ? parcel->dataPosition() : 0;
109}
110
Makoto Onukib148b6c2017-06-27 13:38:38 -0700111static jint android_os_Parcel_dataCapacity(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800112{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800113 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800114 return parcel ? parcel->dataCapacity() : 0;
115}
116
Adrian Roos04505652015-10-22 16:12:01 -0700117static jlong android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800118{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800119 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800120 if (parcel != NULL) {
121 const status_t err = parcel->setDataSize(size);
Michael Wachenschwanz138bebf2017-05-18 22:09:18 +0000122 if (err != NO_ERROR) {
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800123 signalExceptionForError(env, clazz, err);
124 }
Adrian Roos04505652015-10-22 16:12:01 -0700125 return parcel->getOpenAshmemSize();
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800126 }
Adrian Roos04505652015-10-22 16:12:01 -0700127 return 0;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800128}
129
Makoto Onukib148b6c2017-06-27 13:38:38 -0700130static void android_os_Parcel_setDataPosition(jlong nativePtr, jint pos)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800131{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800132 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800133 if (parcel != NULL) {
134 parcel->setDataPosition(pos);
135 }
136}
137
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000138static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800139{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800140 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800141 if (parcel != NULL) {
142 const status_t err = parcel->setDataCapacity(size);
143 if (err != NO_ERROR) {
144 signalExceptionForError(env, clazz, err);
145 }
146 }
147}
148
Makoto Onukib148b6c2017-06-27 13:38:38 -0700149static jboolean android_os_Parcel_pushAllowFds(jlong nativePtr, jboolean allowFds)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800150{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800151 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800152 jboolean ret = JNI_TRUE;
153 if (parcel != NULL) {
154 ret = (jboolean)parcel->pushAllowFds(allowFds);
155 }
156 return ret;
157}
158
Makoto Onukib148b6c2017-06-27 13:38:38 -0700159static void android_os_Parcel_restoreAllowFds(jlong nativePtr, jboolean lastValue)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800160{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800161 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800162 if (parcel != NULL) {
163 parcel->restoreAllowFds((bool)lastValue);
164 }
165}
166
Jocelyn Dang46100442017-05-05 15:40:49 -0700167static void android_os_Parcel_writeByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
168 jobject data, jint offset, jint length)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800169{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800170 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800171 if (parcel == NULL) {
172 return;
173 }
174
175 const status_t err = parcel->writeInt32(length);
176 if (err != NO_ERROR) {
177 signalExceptionForError(env, clazz, err);
178 return;
179 }
180
181 void* dest = parcel->writeInplace(length);
182 if (dest == NULL) {
183 signalExceptionForError(env, clazz, NO_MEMORY);
184 return;
185 }
186
187 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
188 if (ar) {
189 memcpy(dest, ar + offset, length);
190 env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
191 }
192}
193
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700194static void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
195 jint offset, jint length) {
196 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
197 if (parcel == NULL) {
198 return;
199 }
200
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700201 if (data == NULL) {
202 const status_t err = parcel->writeInt32(-1);
203 if (err != NO_ERROR) {
204 signalExceptionForError(env, clazz, err);
205 }
206 return;
207 }
208
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700209 const status_t err = parcel->writeInt32(length);
210 if (err != NO_ERROR) {
211 signalExceptionForError(env, clazz, err);
212 return;
213 }
214
215 android::Parcel::WritableBlob blob;
Jeff Browna316c5d2015-06-05 15:14:06 -0700216 android::status_t err2 = parcel->writeBlob(length, false, &blob);
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700217 if (err2 != NO_ERROR) {
218 signalExceptionForError(env, clazz, err2);
219 return;
220 }
221
222 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
223 if (ar == NULL) {
224 memset(blob.data(), 0, length);
225 } else {
226 memcpy(blob.data(), ar + offset, length);
227 env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
228 }
229
230 blob.release();
231}
232
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000233static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
Jeff Sharkey047238c2012-03-07 16:51:38 -0800234 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Brian Carlstrom849ea022015-06-23 18:02:12 -0700235 if (parcel != NULL) {
236 const status_t err = parcel->writeInt32(val);
237 if (err != NO_ERROR) {
238 signalExceptionForError(env, clazz, err);
239 }
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800240 }
241}
242
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000243static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jlong nativePtr, jlong val)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800244{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800245 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800246 if (parcel != NULL) {
247 const status_t err = parcel->writeInt64(val);
248 if (err != NO_ERROR) {
249 signalExceptionForError(env, clazz, err);
250 }
251 }
252}
253
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000254static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jlong nativePtr, jfloat val)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800255{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800256 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800257 if (parcel != NULL) {
258 const status_t err = parcel->writeFloat(val);
259 if (err != NO_ERROR) {
260 signalExceptionForError(env, clazz, err);
261 }
262 }
263}
264
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000265static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativePtr, jdouble val)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800266{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800267 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800268 if (parcel != NULL) {
269 const status_t err = parcel->writeDouble(val);
270 if (err != NO_ERROR) {
271 signalExceptionForError(env, clazz, err);
272 }
273 }
274}
275
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000276static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800277{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800278 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800279 if (parcel != NULL) {
280 status_t err = NO_MEMORY;
281 if (val) {
282 const jchar* str = env->GetStringCritical(val, 0);
283 if (str) {
Dan Albert66987492014-11-20 11:41:21 -0800284 err = parcel->writeString16(
285 reinterpret_cast<const char16_t*>(str),
286 env->GetStringLength(val));
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800287 env->ReleaseStringCritical(val, str);
288 }
289 } else {
290 err = parcel->writeString16(NULL, 0);
291 }
292 if (err != NO_ERROR) {
293 signalExceptionForError(env, clazz, err);
294 }
295 }
296}
297
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000298static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800299{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800300 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800301 if (parcel != NULL) {
302 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
303 if (err != NO_ERROR) {
304 signalExceptionForError(env, clazz, err);
305 }
306 }
307}
308
Adrian Roos04505652015-10-22 16:12:01 -0700309static jlong android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800310{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800311 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800312 if (parcel != NULL) {
313 const status_t err =
314 parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
315 if (err != NO_ERROR) {
316 signalExceptionForError(env, clazz, err);
317 }
Adrian Roos04505652015-10-22 16:12:01 -0700318 return parcel->getOpenAshmemSize();
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800319 }
Adrian Roos04505652015-10-22 16:12:01 -0700320 return 0;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800321}
322
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000323static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800324{
325 jbyteArray ret = NULL;
326
Jeff Sharkey047238c2012-03-07 16:51:38 -0800327 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800328 if (parcel != NULL) {
329 int32_t len = parcel->readInt32();
330
331 // sanity check the stored length against the true data size
332 if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
333 ret = env->NewByteArray(len);
334
335 if (ret != NULL) {
336 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
337 if (a2) {
338 const void* data = parcel->readInplace(len);
Narayan Kamathd423f672018-08-08 13:46:29 +0100339 if (data) {
340 memcpy(a2, data, len);
341 }
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800342 env->ReleasePrimitiveArrayCritical(ret, a2, 0);
Narayan Kamathd423f672018-08-08 13:46:29 +0100343 if (!data) {
344 ret = NULL;
345 }
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800346 }
347 }
348 }
349 }
350
351 return ret;
352}
353
Jocelyn Dang46100442017-05-05 15:40:49 -0700354static jboolean android_os_Parcel_readByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
355 jobject dest, jint destLen)
356{
357 jboolean ret = JNI_FALSE;
358 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
359 if (parcel == NULL) {
360 return ret;
361 }
362
363 int32_t len = parcel->readInt32();
364 if (len >= 0 && len <= (int32_t)parcel->dataAvail() && len == destLen) {
365 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)dest, 0);
366 if (ar) {
367 const void* data = parcel->readInplace(len);
Narayan Kamathd423f672018-08-08 13:46:29 +0100368 if (data) {
369 memcpy(ar, data, len);
370 ret = JNI_TRUE;
371 } else {
372 ret = JNI_FALSE;
373 }
374
Jocelyn Dang46100442017-05-05 15:40:49 -0700375 env->ReleasePrimitiveArrayCritical((jarray)dest, ar, 0);
Jocelyn Dang46100442017-05-05 15:40:49 -0700376 }
377 }
378 return ret;
379}
380
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700381static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
382{
383 jbyteArray ret = NULL;
384
385 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
386 if (parcel != NULL) {
387 int32_t len = parcel->readInt32();
388 if (len >= 0) {
389 android::Parcel::ReadableBlob blob;
390 android::status_t err = parcel->readBlob(len, &blob);
391 if (err != NO_ERROR) {
392 signalExceptionForError(env, clazz, err);
393 return NULL;
394 }
395
396 ret = env->NewByteArray(len);
397 if (ret != NULL) {
398 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
399 if (a2) {
400 memcpy(a2, blob.data(), len);
401 env->ReleasePrimitiveArrayCritical(ret, a2, 0);
402 }
403 }
404 blob.release();
405 }
406 }
407
408 return ret;
409}
410
Makoto Onukib148b6c2017-06-27 13:38:38 -0700411static jint android_os_Parcel_readInt(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800412{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800413 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800414 if (parcel != NULL) {
415 return parcel->readInt32();
416 }
417 return 0;
418}
419
Makoto Onukib148b6c2017-06-27 13:38:38 -0700420static jlong android_os_Parcel_readLong(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800421{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800422 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800423 if (parcel != NULL) {
424 return parcel->readInt64();
425 }
426 return 0;
427}
428
Makoto Onukib148b6c2017-06-27 13:38:38 -0700429static jfloat android_os_Parcel_readFloat(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800430{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800431 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800432 if (parcel != NULL) {
433 return parcel->readFloat();
434 }
435 return 0;
436}
437
Makoto Onukib148b6c2017-06-27 13:38:38 -0700438static jdouble android_os_Parcel_readDouble(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800439{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800440 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800441 if (parcel != NULL) {
442 return parcel->readDouble();
443 }
444 return 0;
445}
446
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000447static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800448{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800449 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800450 if (parcel != NULL) {
451 size_t len;
452 const char16_t* str = parcel->readString16Inplace(&len);
453 if (str) {
Dan Albert66987492014-11-20 11:41:21 -0800454 return env->NewString(reinterpret_cast<const jchar*>(str), len);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800455 }
456 return NULL;
457 }
458 return NULL;
459}
460
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000461static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800462{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800463 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800464 if (parcel != NULL) {
465 return javaObjectForIBinder(env, parcel->readStrongBinder());
466 }
467 return NULL;
468}
469
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000470static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800471{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800472 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800473 if (parcel != NULL) {
474 int fd = parcel->readFileDescriptor();
475 if (fd < 0) return NULL;
Nick Kralevichc10f60a2019-01-14 10:37:01 -0800476 fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800477 if (fd < 0) return NULL;
478 return jniCreateFileDescriptor(env, fd);
479 }
480 return NULL;
481}
482
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000483static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800484{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800485 Parcel* parcel = new Parcel();
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000486 return reinterpret_cast<jlong>(parcel);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800487}
488
Adrian Roos04505652015-10-22 16:12:01 -0700489static jlong android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkey047238c2012-03-07 16:51:38 -0800490{
491 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
492 if (parcel != NULL) {
493 parcel->freeData();
Adrian Roos04505652015-10-22 16:12:01 -0700494 return parcel->getOpenAshmemSize();
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800495 }
Adrian Roos04505652015-10-22 16:12:01 -0700496 return 0;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800497}
498
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000499static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800500{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800501 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
502 delete parcel;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800503}
504
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000505static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800506{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800507 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800508 if (parcel == NULL) {
509 return NULL;
510 }
511
512 // do not marshall if there are binder objects in the parcel
513 if (parcel->objectsCount())
514 {
515 jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
516 return NULL;
517 }
518
519 jbyteArray ret = env->NewByteArray(parcel->dataSize());
520
521 if (ret != NULL)
522 {
523 jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
524 if (array != NULL)
525 {
526 memcpy(array, parcel->data(), parcel->dataSize());
527 env->ReleasePrimitiveArrayCritical(ret, array, 0);
528 }
529 }
530
531 return ret;
532}
533
Adrian Roos04505652015-10-22 16:12:01 -0700534static jlong android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
535 jbyteArray data, jint offset, jint length)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800536{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800537 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800538 if (parcel == NULL || length < 0) {
Adrian Roos04505652015-10-22 16:12:01 -0700539 return 0;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800540 }
541
542 jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
543 if (array)
544 {
545 parcel->setDataSize(length);
546 parcel->setDataPosition(0);
547
548 void* raw = parcel->writeInplace(length);
549 memcpy(raw, (array + offset), length);
550
551 env->ReleasePrimitiveArrayCritical(data, array, 0);
552 }
Adrian Roos04505652015-10-22 16:12:01 -0700553 return parcel->getOpenAshmemSize();
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800554}
555
Dianne Hackborn7da13d72017-04-04 17:17:35 -0700556static jint android_os_Parcel_compareData(JNIEnv* env, jclass clazz, jlong thisNativePtr,
557 jlong otherNativePtr)
558{
559 Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
560 if (thisParcel == NULL) {
561 return 0;
562 }
563 Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
564 if (otherParcel == NULL) {
565 return thisParcel->getOpenAshmemSize();
566 }
567
568 return thisParcel->compareData(*otherParcel);
569}
570
Adrian Roos04505652015-10-22 16:12:01 -0700571static jlong android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
572 jlong otherNativePtr, jint offset, jint length)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800573{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800574 Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800575 if (thisParcel == NULL) {
Adrian Roos04505652015-10-22 16:12:01 -0700576 return 0;
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800577 }
Jeff Sharkey047238c2012-03-07 16:51:38 -0800578 Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800579 if (otherParcel == NULL) {
Adrian Roos04505652015-10-22 16:12:01 -0700580 return thisParcel->getOpenAshmemSize();
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800581 }
582
583 status_t err = thisParcel->appendFrom(otherParcel, offset, length);
584 if (err != NO_ERROR) {
585 signalExceptionForError(env, clazz, err);
586 }
Adrian Roos04505652015-10-22 16:12:01 -0700587 return thisParcel->getOpenAshmemSize();
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800588}
589
Makoto Onukib148b6c2017-06-27 13:38:38 -0700590static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800591{
592 jboolean ret = JNI_FALSE;
Jeff Sharkey047238c2012-03-07 16:51:38 -0800593 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800594 if (parcel != NULL) {
595 if (parcel->hasFileDescriptors()) {
596 ret = JNI_TRUE;
597 }
598 }
599 return ret;
600}
601
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000602static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr,
Jeff Sharkey047238c2012-03-07 16:51:38 -0800603 jstring name)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800604{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800605 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800606 if (parcel != NULL) {
607 // In the current implementation, the token is just the serialized interface name that
608 // the caller expects to be invoking
609 const jchar* str = env->GetStringCritical(name, 0);
610 if (str != NULL) {
Dan Albert66987492014-11-20 11:41:21 -0800611 parcel->writeInterfaceToken(String16(
612 reinterpret_cast<const char16_t*>(str),
613 env->GetStringLength(name)));
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800614 env->ReleaseStringCritical(name, str);
615 }
616 }
617}
618
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000619static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800620{
Jeff Sharkey047238c2012-03-07 16:51:38 -0800621 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800622 if (parcel != NULL) {
623 const jchar* str = env->GetStringCritical(name, 0);
624 if (str) {
625 IPCThreadState* threadState = IPCThreadState::self();
626 const int32_t oldPolicy = threadState->getStrictModePolicy();
627 const bool isValid = parcel->enforceInterface(
Dan Albert66987492014-11-20 11:41:21 -0800628 String16(reinterpret_cast<const char16_t*>(str),
629 env->GetStringLength(name)),
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800630 threadState);
631 env->ReleaseStringCritical(name, str);
632 if (isValid) {
633 const int32_t newPolicy = threadState->getStrictModePolicy();
634 if (oldPolicy != newPolicy) {
635 // Need to keep the Java-level thread-local strict
636 // mode policy in sync for the libcore
637 // enforcements, which involves an upcall back
638 // into Java. (We can't modify the
639 // Parcel.enforceInterface signature, as it's
640 // pseudo-public, and used via AIDL
641 // auto-generation...)
642 set_dalvik_blockguard_policy(env, newPolicy);
643 }
644 return; // everything was correct -> return silently
645 }
646 }
647 }
648
649 // all error conditions wind up here
650 jniThrowException(env, "java/lang/SecurityException",
651 "Binder invocation to an incorrect interface");
652}
653
Dianne Hackbornfabb70b2014-11-11 12:22:36 -0800654static jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz)
655{
656 return Parcel::getGlobalAllocSize();
657}
658
659static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz)
660{
661 return Parcel::getGlobalAllocCount();
662}
663
Makoto Onukib148b6c2017-06-27 13:38:38 -0700664static jlong android_os_Parcel_getBlobAshmemSize(jlong nativePtr)
Dan Sandler5ce04302015-04-09 23:50:15 -0400665{
666 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
667 if (parcel != NULL) {
668 return parcel->getBlobAshmemSize();
669 }
670 return 0;
671}
672
Olivier Gaillardbab444a2019-01-30 17:11:40 +0000673static jint android_os_Parcel_readCallingWorkSourceUid(jlong nativePtr)
674{
675 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
676 if (parcel != NULL) {
677 return parcel->readCallingWorkSourceUid();
678 }
679 return IPCThreadState::kUnsetWorkSource;
680}
681
682static jboolean android_os_Parcel_replaceCallingWorkSourceUid(jlong nativePtr, jint uid)
683{
684 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
685 if (parcel != NULL) {
686 return parcel->replaceCallingWorkSourceUid(uid);
687 }
688 return false;
689}
690
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800691// ----------------------------------------------------------------------------
692
693static const JNINativeMethod gParcelMethods[] = {
Makoto Onukib148b6c2017-06-27 13:38:38 -0700694 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700695 {"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700696 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700697 {"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700698 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700699 {"nativeDataPosition", "(J)I", (void*)android_os_Parcel_dataPosition},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700700 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700701 {"nativeDataCapacity", "(J)I", (void*)android_os_Parcel_dataCapacity},
702 // @FastNative
703 {"nativeSetDataSize", "(JI)J", (void*)android_os_Parcel_setDataSize},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700704 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700705 {"nativeSetDataPosition", "(JI)V", (void*)android_os_Parcel_setDataPosition},
706 // @FastNative
707 {"nativeSetDataCapacity", "(JI)V", (void*)android_os_Parcel_setDataCapacity},
Jeff Sharkey047238c2012-03-07 16:51:38 -0800708
Makoto Onukib148b6c2017-06-27 13:38:38 -0700709 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700710 {"nativePushAllowFds", "(JZ)Z", (void*)android_os_Parcel_pushAllowFds},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700711 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700712 {"nativeRestoreAllowFds", "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
Jeff Sharkey047238c2012-03-07 16:51:38 -0800713
Jocelyn Dang46100442017-05-05 15:40:49 -0700714 {"nativeWriteByteArray", "(J[BII)V", (void*)android_os_Parcel_writeByteArray},
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700715 {"nativeWriteBlob", "(J[BII)V", (void*)android_os_Parcel_writeBlob},
John Reck71207b52016-09-28 13:28:09 -0700716 // @FastNative
717 {"nativeWriteInt", "(JI)V", (void*)android_os_Parcel_writeInt},
718 // @FastNative
719 {"nativeWriteLong", "(JJ)V", (void*)android_os_Parcel_writeLong},
720 // @FastNative
721 {"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat},
722 // @FastNative
723 {"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble},
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000724 {"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
725 {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
Adrian Roos04505652015-10-22 16:12:01 -0700726 {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
Jeff Sharkey047238c2012-03-07 16:51:38 -0800727
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000728 {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray},
Jocelyn Dang46100442017-05-05 15:40:49 -0700729 {"nativeReadByteArray", "(J[BI)Z", (void*)android_os_Parcel_readByteArray},
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700730 {"nativeReadBlob", "(J)[B", (void*)android_os_Parcel_readBlob},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700731 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700732 {"nativeReadInt", "(J)I", (void*)android_os_Parcel_readInt},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700733 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700734 {"nativeReadLong", "(J)J", (void*)android_os_Parcel_readLong},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700735 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700736 {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700737 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700738 {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble},
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000739 {"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
740 {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
741 {"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
Jeff Sharkey047238c2012-03-07 16:51:38 -0800742
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000743 {"nativeCreate", "()J", (void*)android_os_Parcel_create},
Adrian Roos04505652015-10-22 16:12:01 -0700744 {"nativeFreeBuffer", "(J)J", (void*)android_os_Parcel_freeBuffer},
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000745 {"nativeDestroy", "(J)V", (void*)android_os_Parcel_destroy},
Jeff Sharkey047238c2012-03-07 16:51:38 -0800746
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000747 {"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall},
Adrian Roos04505652015-10-22 16:12:01 -0700748 {"nativeUnmarshall", "(J[BII)J", (void*)android_os_Parcel_unmarshall},
Dianne Hackborn7da13d72017-04-04 17:17:35 -0700749 {"nativeCompareData", "(JJ)I", (void*)android_os_Parcel_compareData},
Adrian Roos04505652015-10-22 16:12:01 -0700750 {"nativeAppendFrom", "(JJII)J", (void*)android_os_Parcel_appendFrom},
Makoto Onukib148b6c2017-06-27 13:38:38 -0700751 // @CriticalNative
John Reck71207b52016-09-28 13:28:09 -0700752 {"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000753 {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
754 {"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
Dianne Hackbornfabb70b2014-11-11 12:22:36 -0800755
756 {"getGlobalAllocSize", "()J", (void*)android_os_Parcel_getGlobalAllocSize},
757 {"getGlobalAllocCount", "()J", (void*)android_os_Parcel_getGlobalAllocCount},
Dan Sandler5ce04302015-04-09 23:50:15 -0400758
Makoto Onukib148b6c2017-06-27 13:38:38 -0700759 // @CriticalNative
Dan Sandleraa861662015-04-21 10:24:32 -0400760 {"nativeGetBlobAshmemSize", "(J)J", (void*)android_os_Parcel_getBlobAshmemSize},
Olivier Gaillardbab444a2019-01-30 17:11:40 +0000761
762 // @CriticalNative
763 {"nativeReadCallingWorkSourceUid", "(J)I", (void*)android_os_Parcel_readCallingWorkSourceUid},
764 // @CriticalNative
765 {"nativeReplaceCallingWorkSourceUid", "(JI)Z", (void*)android_os_Parcel_replaceCallingWorkSourceUid},
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800766};
767
768const char* const kParcelPathName = "android/os/Parcel";
769
770int register_android_os_Parcel(JNIEnv* env)
771{
Andreas Gampe987f79f2014-11-18 17:29:46 -0800772 jclass clazz = FindClassOrDie(env, kParcelPathName);
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800773
Andreas Gampe987f79f2014-11-18 17:29:46 -0800774 gParcelOffsets.clazz = MakeGlobalRefOrDie(env, clazz);
775 gParcelOffsets.mNativePtr = GetFieldIDOrDie(env, clazz, "mNativePtr", "J");
776 gParcelOffsets.obtain = GetStaticMethodIDOrDie(env, clazz, "obtain", "()Landroid/os/Parcel;");
777 gParcelOffsets.recycle = GetMethodIDOrDie(env, clazz, "recycle", "()V");
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800778
Andreas Gampe987f79f2014-11-18 17:29:46 -0800779 return RegisterMethodsOrDie(env, kParcelPathName, gParcelMethods, NELEM(gParcelMethods));
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800780}
781
782};