Adds framework support for hidl-gen Java backend. (to support structs)

Bug: 30575790
Change-Id: Ida30d8fe7a1b210e98f1a0ea5d429a0112f9ef3f
Signed-off-by: Iliyan Malchev <malchev@google.com>
This commit is contained in:
Andreas Huber
2016-08-25 11:21:21 -07:00
committed by Martijn Coenen
parent e1eb45d8d6
commit 50546a98ed
8 changed files with 704 additions and 10 deletions

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os;
import libcore.util.NativeAllocationRegistry;
/** @hide */
public class HwBlob {
private static final String TAG = "HwBlob";
private static final NativeAllocationRegistry sNativeRegistry;
public HwBlob(int size) {
native_setup(size);
sNativeRegistry.registerNativeAllocation(
this,
mNativeContext);
}
public native final boolean getBool(long offset);
public native final byte getInt8(long offset);
public native final short getInt16(long offset);
public native final int getInt32(long offset);
public native final long getInt64(long offset);
public native final float getFloat(long offset);
public native final double getDouble(long offset);
public native final String getString(long offset);
public native final void putBool(long offset, boolean x);
public native final void putInt8(long offset, byte x);
public native final void putInt16(long offset, short x);
public native final void putInt32(long offset, int x);
public native final void putInt64(long offset, long x);
public native final void putFloat(long offset, float x);
public native final void putDouble(long offset, double x);
public native final void putString(long offset, String x);
public native final void putBlob(long offset, HwBlob blob);
public native final long handle();
// Returns address of the "freeFunction".
private static native final long native_init();
private native final void native_setup(int size);
static {
long freeFunction = native_init();
sNativeRegistry = new NativeAllocationRegistry(
HwBlob.class.getClassLoader(),
freeFunction,
128 /* size */);
}
private long mNativeContext;
}

View File

@@ -101,6 +101,14 @@ public class HwParcel {
public native final IHwBinder readStrongBinder();
// Handle is stored as part of the blob.
public native final HwBlob readBuffer();
public native final HwBlob readEmbeddedBuffer(
long parentHandle, long offset);
public native final void writeBuffer(HwBlob blob);
public native final void writeStatus(int status);
public native final void verifySuccess();
public native final void releaseTemporaryStorage();

View File

@@ -81,6 +81,7 @@ LOCAL_SRC_FILES:= \
android_text_StaticLayout.cpp \
android_os_Debug.cpp \
android_os_HwBinder.cpp \
android_os_HwBlob.cpp \
android_os_HwParcel.cpp \
android_os_HwRemoteBinder.cpp \
android_os_MemoryFile.cpp \

View File

@@ -157,6 +157,7 @@ extern int register_android_database_SQLiteDebug(JNIEnv* env);
extern int register_android_nio_utils(JNIEnv* env);
extern int register_android_os_Debug(JNIEnv* env);
extern int register_android_os_HwBinder(JNIEnv *env);
extern int register_android_os_HwBlob(JNIEnv *env);
extern int register_android_os_HwParcel(JNIEnv *env);
extern int register_android_os_HwRemoteBinder(JNIEnv *env);
extern int register_android_os_MessageQueue(JNIEnv* env);
@@ -1291,6 +1292,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
REG_JNI(register_android_os_HwBinder),
REG_JNI(register_android_os_HwBlob),
REG_JNI(register_android_os_HwParcel),
REG_JNI(register_android_os_HwRemoteBinder),
REG_JNI(register_android_nio_utils),

View File

@@ -0,0 +1,452 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "android_os_HwBlob"
#include <android-base/logging.h>
#include "android_os_HwBlob.h"
#include "android_os_HwParcel.h"
#include <JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <hwbinder/Status.h>
#include <nativehelper/ScopedLocalRef.h>
#include "core_jni_helpers.h"
using android::AndroidRuntime;
using android::hardware::hidl_string;
#define PACKAGE_PATH "android/os"
#define CLASS_NAME "HwBlob"
#define CLASS_PATH PACKAGE_PATH "/" CLASS_NAME
namespace android {
static struct fields_t {
jfieldID contextID;
jmethodID constructID;
} gFields;
// static
void JHwBlob::InitClass(JNIEnv *env) {
ScopedLocalRef<jclass> clazz(
env, FindClassOrDie(env, CLASS_PATH));
gFields.contextID =
GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
gFields.constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "(I)V");
}
// static
sp<JHwBlob> JHwBlob::SetNativeContext(
JNIEnv *env, jobject thiz, const sp<JHwBlob> &context) {
sp<JHwBlob> old = (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
if (context != NULL) {
context->incStrong(NULL /* id */);
}
if (old != NULL) {
old->decStrong(NULL /* id */);
}
env->SetLongField(thiz, gFields.contextID, (long)context.get());
return old;
}
// static
sp<JHwBlob> JHwBlob::GetNativeContext(JNIEnv *env, jobject thiz) {
return (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
}
JHwBlob::JHwBlob(JNIEnv *env, jobject thiz, size_t size)
: mBuffer(nullptr),
mSize(size),
mOwnsBuffer(true),
mHandle(0) {
jclass clazz = env->GetObjectClass(thiz);
CHECK(clazz != NULL);
mClass = (jclass)env->NewGlobalRef(clazz);
mObject = env->NewWeakGlobalRef(thiz);
if (size > 0) {
mBuffer = malloc(size);
}
}
JHwBlob::~JHwBlob() {
if (mOwnsBuffer) {
free(mBuffer);
mBuffer = nullptr;
}
JNIEnv *env = AndroidRuntime::getJNIEnv();
env->DeleteWeakGlobalRef(mObject);
mObject = NULL;
env->DeleteGlobalRef(mClass);
mClass = NULL;
}
void JHwBlob::setTo(const void *ptr, size_t handle) {
CHECK_EQ(mSize, 0u);
CHECK(mBuffer == nullptr);
mBuffer = const_cast<void *>(ptr);
mSize = SIZE_MAX; // XXX
mOwnsBuffer = false;
mHandle = handle;
}
status_t JHwBlob::getHandle(size_t *handle) const {
if (mOwnsBuffer) {
return INVALID_OPERATION;
}
*handle = mHandle;
return OK;
}
status_t JHwBlob::read(size_t offset, void *data, size_t size) const {
if (offset + size > mSize) {
return -ERANGE;
}
memcpy(data, (const uint8_t *)mBuffer + offset, size);
return OK;
}
status_t JHwBlob::write(size_t offset, const void *data, size_t size) {
if (offset + size > mSize) {
return -ERANGE;
}
memcpy((uint8_t *)mBuffer + offset, data, size);
return OK;
}
status_t JHwBlob::getString(size_t offset, const hidl_string **s) const {
if ((offset + sizeof(hidl_string)) > mSize) {
return -ERANGE;
}
*s = reinterpret_cast<const hidl_string *>(
(const uint8_t *)mBuffer + offset);
return OK;
}
const void *JHwBlob::data() const {
return mBuffer;
}
size_t JHwBlob::size() const {
return mSize;
}
status_t JHwBlob::putBlob(size_t offset, const sp<JHwBlob> &blob) {
size_t index = mSubBlobs.add();
BlobInfo *info = &mSubBlobs.editItemAt(index);
info->mOffset = offset;
info->mBlob = blob;
const void *data = blob->data();
return write(offset, &data, sizeof(data));
}
status_t JHwBlob::writeToParcel(hardware::Parcel *parcel) const {
size_t handle;
status_t err = parcel->writeBuffer(data(), size(), &handle);
if (err != OK) {
return err;
}
for (size_t i = 0; i < mSubBlobs.size(); ++i) {
const BlobInfo &info = mSubBlobs[i];
err = info.mBlob->writeEmbeddedToParcel(parcel, handle, info.mOffset);
if (err != OK) {
return err;
}
}
return OK;
}
status_t JHwBlob::writeEmbeddedToParcel(
hardware::Parcel *parcel,
size_t parentHandle,
size_t parentOffset) const {
size_t handle;
status_t err = parcel->writeEmbeddedBuffer(
data(), size(), &handle, parentHandle, parentOffset);
if (err != OK) {
return err;
}
for (size_t i = 0; i < mSubBlobs.size(); ++i) {
const BlobInfo &info = mSubBlobs[i];
err = info.mBlob->writeEmbeddedToParcel(parcel, handle, info.mOffset);
if (err != OK) {
return err;
}
}
return OK;
}
// static
jobject JHwBlob::NewObject(JNIEnv *env, const void *ptr, size_t handle) {
jobject obj = JHwBlob::NewObject(env, 0 /* size */);
JHwBlob::GetNativeContext(env, obj)->setTo(ptr, handle);
return obj;
}
// static
jobject JHwBlob::NewObject(JNIEnv *env, size_t size) {
ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
jmethodID constructID =
GetMethodIDOrDie(env, clazz.get(), "<init>", "(I)V");
// XXX Again cannot refer to gFields.constructID because InitClass may
// not have been called yet.
return env->NewObject(clazz.get(), constructID, size);
}
} // namespace android
////////////////////////////////////////////////////////////////////////////////
using namespace android;
static void releaseNativeContext(void *nativeContext) {
sp<JHwBlob> parcel = (JHwBlob *)nativeContext;
if (parcel != NULL) {
parcel->decStrong(NULL /* id */);
}
}
static jlong JHwBlob_native_init(JNIEnv *env) {
JHwBlob::InitClass(env);
return reinterpret_cast<jlong>(&releaseNativeContext);
}
static void JHwBlob_native_setup(
JNIEnv *env, jobject thiz, jint size) {
sp<JHwBlob> context = new JHwBlob(env, thiz, size);
JHwBlob::SetNativeContext(env, thiz, context);
}
#define DEFINE_BLOB_GETTER(Suffix,Type) \
static Type JHwBlob_native_get ## Suffix( \
JNIEnv *env, jobject thiz, jlong offset) { \
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz); \
\
Type x; \
status_t err = blob->read(offset, &x, sizeof(x)); \
\
if (err != OK) { \
signalExceptionForError(env, err); \
return 0; \
} \
\
return x; \
}
DEFINE_BLOB_GETTER(Int8,jbyte)
DEFINE_BLOB_GETTER(Int16,jshort)
DEFINE_BLOB_GETTER(Int32,jint)
DEFINE_BLOB_GETTER(Int64,jlong)
DEFINE_BLOB_GETTER(Float,jfloat)
DEFINE_BLOB_GETTER(Double,jdouble)
static jboolean JHwBlob_native_getBool(
JNIEnv *env, jobject thiz, jlong offset) {
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
bool x;
status_t err = blob->read(offset, &x, sizeof(x));
if (err != OK) {
signalExceptionForError(env, err);
return 0;
}
return (jboolean)x;
}
static jstring JHwBlob_native_getString(
JNIEnv *env, jobject thiz, jlong offset) {
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
const hidl_string *s;
status_t err = blob->getString(offset, &s);
if (err != OK) {
signalExceptionForError(env, err);
return nullptr;
}
return env->NewStringUTF(s->c_str());
}
#define DEFINE_BLOB_PUTTER(Suffix,Type) \
static void JHwBlob_native_put ## Suffix( \
JNIEnv *env, jobject thiz, jlong offset, Type x) { \
\
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz); \
\
status_t err = blob->write(offset, &x, sizeof(x)); \
\
if (err != OK) { \
signalExceptionForError(env, err); \
} \
}
DEFINE_BLOB_PUTTER(Int8,jbyte)
DEFINE_BLOB_PUTTER(Int16,jshort)
DEFINE_BLOB_PUTTER(Int32,jint)
DEFINE_BLOB_PUTTER(Int64,jlong)
DEFINE_BLOB_PUTTER(Float,jfloat)
DEFINE_BLOB_PUTTER(Double,jdouble)
static void JHwBlob_native_putBool(
JNIEnv *env, jobject thiz, jlong offset, jboolean x) {
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
bool b = (bool)x;
status_t err = blob->write(offset, &b, sizeof(b));
if (err != OK) {
signalExceptionForError(env, err);
}
}
static void JHwBlob_native_putString(
JNIEnv *env, jobject thiz, jlong offset, jstring stringObj) {
if (stringObj == nullptr) {
jniThrowException(env, "java/lang/NullPointerException", nullptr);
return;
}
const char *s = env->GetStringUTFChars(stringObj, nullptr);
if (s == nullptr) {
return;
}
size_t size = strlen(s) + 1;
ScopedLocalRef<jobject> subBlobObj(env, JHwBlob::NewObject(env, size));
sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, subBlobObj.get());
subBlob->write(0 /* offset */, s, size);
env->ReleaseStringUTFChars(stringObj, s);
s = nullptr;
hidl_string tmp;
tmp.setToExternal(static_cast<const char *>(subBlob->data()), size);
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
blob->write(offset, &tmp, sizeof(tmp));
blob->putBlob(offset + hidl_string::kOffsetOfBuffer, subBlob);
}
static void JHwBlob_native_putBlob(
JNIEnv *env, jobject thiz, jlong offset, jobject blobObj) {
if (blobObj == nullptr) {
jniThrowException(env, "java/lang/NullPointerException", nullptr);
return;
}
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, blobObj);
blob->putBlob(offset, subBlob);
}
static jlong JHwBlob_native_handle(JNIEnv *env, jobject thiz) {
size_t handle;
status_t err = JHwBlob::GetNativeContext(env, thiz)->getHandle(&handle);
if (err != OK) {
signalExceptionForError(env, err);
return 0;
}
return handle;
}
static JNINativeMethod gMethods[] = {
{ "native_init", "()J", (void *)JHwBlob_native_init },
{ "native_setup", "(I)V", (void *)JHwBlob_native_setup },
{ "getBool", "(J)Z", (void *)JHwBlob_native_getBool },
{ "getInt8", "(J)B", (void *)JHwBlob_native_getInt8 },
{ "getInt16", "(J)S", (void *)JHwBlob_native_getInt16 },
{ "getInt32", "(J)I", (void *)JHwBlob_native_getInt32 },
{ "getInt64", "(J)J", (void *)JHwBlob_native_getInt64 },
{ "getFloat", "(J)F", (void *)JHwBlob_native_getFloat },
{ "getDouble", "(J)D", (void *)JHwBlob_native_getDouble },
{ "getString", "(J)Ljava/lang/String;", (void *)JHwBlob_native_getString },
{ "putBool", "(JZ)V", (void *)JHwBlob_native_putBool },
{ "putInt8", "(JB)V", (void *)JHwBlob_native_putInt8 },
{ "putInt16", "(JS)V", (void *)JHwBlob_native_putInt16 },
{ "putInt32", "(JI)V", (void *)JHwBlob_native_putInt32 },
{ "putInt64", "(JJ)V", (void *)JHwBlob_native_putInt64 },
{ "putFloat", "(JF)V", (void *)JHwBlob_native_putFloat },
{ "putDouble", "(JD)V", (void *)JHwBlob_native_putDouble },
{ "putString", "(JLjava/lang/String;)V", (void *)JHwBlob_native_putString },
{ "putBlob", "(JL" PACKAGE_PATH "/HwBlob;)V",
(void *)JHwBlob_native_putBlob },
{ "handle", "()J", (void *)JHwBlob_native_handle },
};
namespace android {
int register_android_os_HwBlob(JNIEnv *env) {
return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
}
} // namespace android

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_OS_HW_BLOB_H
#define ANDROID_OS_HW_BLOB_H
#include <android-base/macros.h>
#include <jni.h>
#include <hidl/HidlSupport.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
namespace android {
struct JHwBlob : public RefBase {
static void InitClass(JNIEnv *env);
static sp<JHwBlob> SetNativeContext(
JNIEnv *env, jobject thiz, const sp<JHwBlob> &context);
static sp<JHwBlob> GetNativeContext(JNIEnv *env, jobject thiz);
static jobject NewObject(JNIEnv *env, const void *ptr, size_t handle);
static jobject NewObject(JNIEnv *env, size_t size);
JHwBlob(JNIEnv *env, jobject thiz, size_t size);
void setTo(const void *ptr, size_t handle);
status_t getHandle(size_t *handle) const;
status_t read(size_t offset, void *data, size_t size) const;
status_t write(size_t offset, const void *data, size_t size);
status_t getString(
size_t offset, const android::hardware::hidl_string **s) const;
const void *data() const;
size_t size() const;
status_t putBlob(size_t offset, const sp<JHwBlob> &blob);
status_t writeToParcel(hardware::Parcel *parcel) const;
status_t writeEmbeddedToParcel(
hardware::Parcel *parcel,
size_t parentHandle,
size_t parentOffset) const;
protected:
virtual ~JHwBlob();
private:
struct BlobInfo {
size_t mOffset;
sp<JHwBlob> mBlob;
};
jclass mClass;
jobject mObject;
void *mBuffer;
size_t mSize;
bool mOwnsBuffer;
size_t mHandle;
Vector<BlobInfo> mSubBlobs;
DISALLOW_COPY_AND_ASSIGN(JHwBlob);
};
int register_android_os_HwBlob(JNIEnv *env);
} // namespace android
#endif // ANDROID_OS_HW_BLOB_H

View File

@@ -21,6 +21,7 @@
#include "android_os_HwParcel.h"
#include "android_os_HwBinder.h"
#include "android_os_HwBlob.h"
#include "android_os_HwRemoteBinder.h"
#include <JNIHelp.h>
@@ -71,6 +72,7 @@ void signalExceptionForError(JNIEnv *env, status_t err) {
break;
}
case -ERANGE:
case BAD_INDEX:
{
jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
@@ -200,8 +202,10 @@ void JHwParcel::setParcel(hardware::Parcel *parcel, bool assumeOwnership) {
jobject JHwParcel::NewObject(JNIEnv *env) {
ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
return env->NewObject(
clazz.get(), gFields.constructID, false /* allocate */);
jmethodID constructID =
GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");
return env->NewObject(clazz.get(), constructID, false /* allocate */);
}
void JHwParcel::setTransactCallback(
@@ -547,9 +551,10 @@ static void JHwParcel_native_writeBoolVector(
sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
hidl_vec<bool> *vec =
(hidl_vec<bool> *)impl->getStorage()->allocTemporaryStorage(
sizeof(hidl_vec<bool>));
void *vecPtr =
impl->getStorage()->allocTemporaryStorage(sizeof(hidl_vec<bool>));
hidl_vec<bool> *vec = new (vecPtr) hidl_vec<bool>;
jsize len = env->GetArrayLength(valObj);
@@ -917,9 +922,10 @@ static void JHwParcel_native_writeStringVector(
sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
string_vec *vec =
(string_vec *)impl->getStorage()->allocTemporaryStorage(
sizeof(string_vec));
void *vecPtr =
impl->getStorage()->allocTemporaryStorage(sizeof(string_vec));
string_vec *vec = new (vecPtr) string_vec;
hidl_string *strings = impl->getStorage()->allocStringArray(len);
vec->setToExternal(strings, len);
@@ -972,6 +978,57 @@ static jobject JHwParcel_native_readStrongBinder(JNIEnv *env, jobject thiz) {
return JHwRemoteBinder::NewObject(env, binder);
}
static jobject JHwParcel_native_readBuffer(JNIEnv *env, jobject thiz) {
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
size_t handle;
const void *ptr = parcel->readBuffer(&handle);
if (ptr == nullptr) {
jniThrowException(env, "java/util/NoSuchElementException", NULL);
return nullptr;
}
return JHwBlob::NewObject(env, ptr, handle);
}
static jobject JHwParcel_native_readEmbeddedBuffer(
JNIEnv *env, jobject thiz, jlong parentHandle, jlong offset) {
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
size_t childHandle;
const void *ptr =
parcel->readEmbeddedBuffer(&childHandle, parentHandle, offset);
if (ptr == nullptr) {
jniThrowException(env, "java/util/NoSuchElementException", NULL);
return 0;
}
return JHwBlob::NewObject(env, ptr, childHandle);
}
static void JHwParcel_native_writeBuffer(
JNIEnv *env, jobject thiz, jobject blobObj) {
if (blobObj == nullptr) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
return;
}
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, blobObj);
status_t err = blob->writeToParcel(parcel);
if (err != OK) {
signalExceptionForError(env, err);
}
}
static JNINativeMethod gMethods[] = {
{ "native_init", "()J", (void *)JHwParcel_native_init },
{ "native_setup", "(Z)V", (void *)JHwParcel_native_setup },
@@ -1062,6 +1119,15 @@ static JNINativeMethod gMethods[] = {
(void *)JHwParcel_native_releaseTemporaryStorage },
{ "send", "()V", (void *)JHwParcel_native_send },
{ "readBuffer", "()L" PACKAGE_PATH "/HwBlob;",
(void *)JHwParcel_native_readBuffer },
{ "readEmbeddedBuffer", "(JJ)L" PACKAGE_PATH "/HwBlob;",
(void *)JHwParcel_native_readEmbeddedBuffer },
{ "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
(void *)JHwParcel_native_writeBuffer },
};
namespace android {

View File

@@ -99,9 +99,9 @@ const hidl_vec<Type> *EphemeralStorage::allocTemporary ## Suffix ## Vector( \
item.mPtr = (void *)val; \
mItems.push_back(item); \
\
hidl_vec<Type> *vec = \
(hidl_vec<Type> *)allocTemporaryStorage(sizeof(hidl_vec<Type>)); \
void *vecPtr = allocTemporaryStorage(sizeof(hidl_vec<Type>)); \
\
hidl_vec<Type> *vec = new (vecPtr) hidl_vec<Type>; \
vec->setToExternal(const_cast<Type *>(val), len); \
\
return vec; \