From 90d7a3e996ee3a6e33e655341c5d301fbe30cd58 Mon Sep 17 00:00:00 2001 From: Sandeep Siddhartha Date: Fri, 25 Jul 2014 16:19:42 -0700 Subject: [PATCH] Add read/writeBlob to Parcel These are {@hide}en for now. Bug: 16516353 Change-Id: Ie1635617ee8611a78be9068a7ce674e34c30301d --- core/java/android/os/Parcel.java | 20 ++++++++++ core/jni/android_os_Parcel.cpp | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 95cb9f3d7b086..59cd97c445f4e 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -246,6 +246,7 @@ public final class Parcel { private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue); private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len); + private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len); private static native void nativeWriteInt(long nativePtr, int val); private static native void nativeWriteLong(long nativePtr, long val); private static native void nativeWriteFloat(long nativePtr, float val); @@ -255,6 +256,7 @@ public final class Parcel { private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); private static native byte[] nativeCreateByteArray(long nativePtr); + private static native byte[] nativeReadBlob(long nativePtr); private static native int nativeReadInt(long nativePtr); private static native long nativeReadLong(long nativePtr); private static native float nativeReadFloat(long nativePtr); @@ -478,6 +480,16 @@ public final class Parcel { nativeWriteByteArray(mNativePtr, b, offset, len); } + /** + * Write a blob of data into the parcel at the current {@link #dataPosition}, + * growing {@link #dataCapacity} if needed. + * @param b Bytes to place into the parcel. + * {@hide} + */ + public final void writeBlob(byte[] b) { + nativeWriteBlob(mNativePtr, b, 0, (b != null) ? b.length : 0); + } + /** * Write an integer value into the parcel at the current dataPosition(), * growing dataCapacity() if needed. @@ -1699,6 +1711,14 @@ public final class Parcel { } } + /** + * Read a blob of data from the parcel and return it as a byte array. + * {@hide} + */ + public final byte[] readBlob() { + return nativeReadBlob(mNativePtr); + } + /** * Read and return a String[] object from the parcel. * {@hide} diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 50f6c73fa0da9..3ba481ed3f219 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -187,6 +187,37 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativ } } +static void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data, + jint offset, jint length) { + Parcel* parcel = reinterpret_cast(nativePtr); + if (parcel == NULL) { + return; + } + + const status_t err = parcel->writeInt32(length); + if (err != NO_ERROR) { + signalExceptionForError(env, clazz, err); + return; + } + + android::Parcel::WritableBlob blob; + android::status_t err2 = parcel->writeBlob(length, &blob); + if (err2 != NO_ERROR) { + signalExceptionForError(env, clazz, err2); + return; + } + + jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0); + if (ar == NULL) { + memset(blob.data(), 0, length); + } else { + memcpy(blob.data(), ar + offset, length); + env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0); + } + + blob.release(); +} + static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) { Parcel* parcel = reinterpret_cast(nativePtr); const status_t err = parcel->writeInt32(val); @@ -297,6 +328,36 @@ static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, j return ret; } +static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr) +{ + jbyteArray ret = NULL; + + Parcel* parcel = reinterpret_cast(nativePtr); + if (parcel != NULL) { + int32_t len = parcel->readInt32(); + if (len >= 0) { + android::Parcel::ReadableBlob blob; + android::status_t err = parcel->readBlob(len, &blob); + if (err != NO_ERROR) { + signalExceptionForError(env, clazz, err); + return NULL; + } + + ret = env->NewByteArray(len); + if (ret != NULL) { + jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); + if (a2) { + memcpy(a2, blob.data(), len); + env->ReleasePrimitiveArrayCritical(ret, a2, 0); + } + } + blob.release(); + } + } + + return ret; +} + static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast(nativePtr); @@ -634,6 +695,7 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeRestoreAllowFds", "(JZ)V", (void*)android_os_Parcel_restoreAllowFds}, {"nativeWriteByteArray", "(J[BII)V", (void*)android_os_Parcel_writeNative}, + {"nativeWriteBlob", "(J[BII)V", (void*)android_os_Parcel_writeBlob}, {"nativeWriteInt", "(JI)V", (void*)android_os_Parcel_writeInt}, {"nativeWriteLong", "(JJ)V", (void*)android_os_Parcel_writeLong}, {"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat}, @@ -643,6 +705,7 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor}, {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray}, + {"nativeReadBlob", "(J)[B", (void*)android_os_Parcel_readBlob}, {"nativeReadInt", "(J)I", (void*)android_os_Parcel_readInt}, {"nativeReadLong", "(J)J", (void*)android_os_Parcel_readLong}, {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat},