Merge changes from topic 'fb-new-project' into stage-aosp-master
* changes: Move Status to libhidl (DO NOT MERGE) Adds framework support for hidl-gen Java backend. (to support structs) (DO NOT MERGE) Add Bool* APIs to HwParcel (DO NOT MERGE) Link against libhidl for HidlSupport/svcmgr (DO NOT MERGE) Support one-way methods in java support for hardware binder (DO NOT MERGE) Initial commit of Java support for hardware binder (DO NOT MERGE)
This commit is contained in:
59
core/java/android/os/HwBinder.java
Normal file
59
core/java/android/os/HwBinder.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 abstract class HwBinder implements IHwBinder {
|
||||
private static final String TAG = "HwBinder";
|
||||
|
||||
private static final NativeAllocationRegistry sNativeRegistry;
|
||||
|
||||
public HwBinder() {
|
||||
native_setup();
|
||||
|
||||
sNativeRegistry.registerNativeAllocation(
|
||||
this,
|
||||
mNativeContext);
|
||||
}
|
||||
|
||||
public final native void transact(
|
||||
int code, HwParcel request, HwParcel reply, int flags);
|
||||
|
||||
public abstract void onTransact(
|
||||
int code, HwParcel request, HwParcel reply, int flags);
|
||||
|
||||
public native final void registerService(String serviceName);
|
||||
public static native final IHwBinder getService(String serviceName);
|
||||
|
||||
// Returns address of the "freeFunction".
|
||||
private static native final long native_init();
|
||||
|
||||
private native final void native_setup();
|
||||
|
||||
static {
|
||||
long freeFunction = native_init();
|
||||
|
||||
sNativeRegistry = new NativeAllocationRegistry(
|
||||
HwBinder.class.getClassLoader(),
|
||||
freeFunction,
|
||||
128 /* size */);
|
||||
}
|
||||
|
||||
private long mNativeContext;
|
||||
}
|
||||
74
core/java/android/os/HwBlob.java
Normal file
74
core/java/android/os/HwBlob.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
134
core/java/android/os/HwParcel.java
Normal file
134
core/java/android/os/HwParcel.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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 HwParcel {
|
||||
private static final String TAG = "HwParcel";
|
||||
|
||||
public static final int STATUS_SUCCESS = 0;
|
||||
public static final int STATUS_ERROR = -1;
|
||||
|
||||
private static final NativeAllocationRegistry sNativeRegistry;
|
||||
|
||||
private HwParcel(boolean allocate) {
|
||||
native_setup(allocate);
|
||||
|
||||
sNativeRegistry.registerNativeAllocation(
|
||||
this,
|
||||
mNativeContext);
|
||||
}
|
||||
|
||||
public HwParcel() {
|
||||
native_setup(true /* allocate */);
|
||||
|
||||
sNativeRegistry.registerNativeAllocation(
|
||||
this,
|
||||
mNativeContext);
|
||||
}
|
||||
|
||||
public native final void writeInterfaceToken(String interfaceName);
|
||||
public native final void writeBool(boolean val);
|
||||
public native final void writeInt8(byte val);
|
||||
public native final void writeInt16(short val);
|
||||
public native final void writeInt32(int val);
|
||||
public native final void writeInt64(long val);
|
||||
public native final void writeFloat(float val);
|
||||
public native final void writeDouble(double val);
|
||||
public native final void writeString(String val);
|
||||
|
||||
public native final void writeBoolArray(int size, boolean[] val);
|
||||
public native final void writeBoolVector(boolean[] val);
|
||||
public native final void writeInt8Array(int size, byte[] val);
|
||||
public native final void writeInt8Vector(byte[] val);
|
||||
public native final void writeInt16Array(int size, short[] val);
|
||||
public native final void writeInt16Vector(short[] val);
|
||||
public native final void writeInt32Array(int size, int[] val);
|
||||
public native final void writeInt32Vector(int[] val);
|
||||
public native final void writeInt64Array(int size, long[] val);
|
||||
public native final void writeInt64Vector(long[] val);
|
||||
public native final void writeFloatArray(int size, float[] val);
|
||||
public native final void writeFloatVector(float[] val);
|
||||
public native final void writeDoubleArray(int size, double[] val);
|
||||
public native final void writeDoubleVector(double[] val);
|
||||
public native final void writeStringArray(int size, String[] val);
|
||||
public native final void writeStringVector(String[] val);
|
||||
|
||||
public native final void writeStrongBinder(IHwBinder binder);
|
||||
|
||||
public native final void enforceInterface(String interfaceName);
|
||||
public native final boolean readBool();
|
||||
public native final byte readInt8();
|
||||
public native final short readInt16();
|
||||
public native final int readInt32();
|
||||
public native final long readInt64();
|
||||
public native final float readFloat();
|
||||
public native final double readDouble();
|
||||
public native final String readString();
|
||||
|
||||
public native final boolean[] readBoolArray(int size);
|
||||
public native final boolean[] readBoolVector();
|
||||
public native final byte[] readInt8Array(int size);
|
||||
public native final byte[] readInt8Vector();
|
||||
public native final short[] readInt16Array(int size);
|
||||
public native final short[] readInt16Vector();
|
||||
public native final int[] readInt32Array(int size);
|
||||
public native final int[] readInt32Vector();
|
||||
public native final long[] readInt64Array(int size);
|
||||
public native final long[] readInt64Vector();
|
||||
public native final float[] readFloatArray(int size);
|
||||
public native final float[] readFloatVector();
|
||||
public native final double[] readDoubleArray(int size);
|
||||
public native final double[] readDoubleVector();
|
||||
public native final String[] readStringArray(int size);
|
||||
public native final String[] readStringVector();
|
||||
|
||||
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();
|
||||
|
||||
public native final void send();
|
||||
|
||||
// Returns address of the "freeFunction".
|
||||
private static native final long native_init();
|
||||
|
||||
private native final void native_setup(boolean allocate);
|
||||
|
||||
static {
|
||||
long freeFunction = native_init();
|
||||
|
||||
sNativeRegistry = new NativeAllocationRegistry(
|
||||
HwParcel.class.getClassLoader(),
|
||||
freeFunction,
|
||||
128 /* size */);
|
||||
}
|
||||
|
||||
private long mNativeContext;
|
||||
}
|
||||
|
||||
56
core/java/android/os/HwRemoteBinder.java
Normal file
56
core/java/android/os/HwRemoteBinder.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 HwRemoteBinder implements IHwBinder {
|
||||
private static final String TAG = "HwRemoteBinder";
|
||||
|
||||
private static final NativeAllocationRegistry sNativeRegistry;
|
||||
|
||||
public HwRemoteBinder() {
|
||||
native_setup_empty();
|
||||
|
||||
sNativeRegistry.registerNativeAllocation(
|
||||
this,
|
||||
mNativeContext);
|
||||
}
|
||||
|
||||
public IHwInterface queryLocalInterface(String descriptor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public native final void transact(
|
||||
int code, HwParcel request, HwParcel reply, int flags);
|
||||
|
||||
private static native final long native_init();
|
||||
|
||||
private native final void native_setup_empty();
|
||||
|
||||
static {
|
||||
long freeFunction = native_init();
|
||||
|
||||
sNativeRegistry = new NativeAllocationRegistry(
|
||||
HwRemoteBinder.class.getClassLoader(),
|
||||
freeFunction,
|
||||
128 /* size */);
|
||||
}
|
||||
|
||||
private long mNativeContext;
|
||||
}
|
||||
29
core/java/android/os/IHwBinder.java
Normal file
29
core/java/android/os/IHwBinder.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/** @hide */
|
||||
public interface IHwBinder {
|
||||
// These MUST match their corresponding libhwbinder/IBinder.h definition !!!
|
||||
public static final int FIRST_CALL_TRANSACTION = 1;
|
||||
public static final int FLAG_ONEWAY = 1;
|
||||
|
||||
public void transact(
|
||||
int code, HwParcel request, HwParcel reply, int flags);
|
||||
|
||||
public IHwInterface queryLocalInterface(String descriptor);
|
||||
}
|
||||
22
core/java/android/os/IHwInterface.java
Normal file
22
core/java/android/os/IHwInterface.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/** @hide */
|
||||
public interface IHwInterface {
|
||||
public IHwBinder asBinder();
|
||||
}
|
||||
@@ -80,6 +80,10 @@ LOCAL_SRC_FILES:= \
|
||||
android_text_AndroidBidi.cpp \
|
||||
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 \
|
||||
android_os_MessageQueue.cpp \
|
||||
android_os_Parcel.cpp \
|
||||
@@ -177,7 +181,8 @@ LOCAL_SRC_FILES:= \
|
||||
com_android_internal_os_PathClassLoaderFactory.cpp \
|
||||
com_android_internal_os_Zygote.cpp \
|
||||
com_android_internal_util_VirtualRefBasePtr.cpp \
|
||||
com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
|
||||
com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp \
|
||||
hwbinder/EphemeralStorage.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(JNI_H_INCLUDE) \
|
||||
@@ -260,6 +265,8 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libradio_metadata \
|
||||
libnativeloader \
|
||||
libmemunreachable \
|
||||
libhidl \
|
||||
libhwbinder \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libhwui \
|
||||
|
||||
@@ -156,6 +156,10 @@ extern int register_android_database_SQLiteGlobal(JNIEnv* env);
|
||||
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);
|
||||
extern int register_android_os_Parcel(JNIEnv* env);
|
||||
extern int register_android_os_SELinux(JNIEnv* env);
|
||||
@@ -1287,6 +1291,10 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_os_SystemProperties),
|
||||
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),
|
||||
REG_JNI(register_android_graphics_Canvas),
|
||||
REG_JNI(register_android_graphics_Graphics),
|
||||
|
||||
288
core/jni/android_os_HwBinder.cpp
Normal file
288
core/jni/android_os_HwBinder.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* 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_HwBinder"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "android_os_HwBinder.h"
|
||||
|
||||
#include "android_os_HwParcel.h"
|
||||
#include "android_os_HwRemoteBinder.h"
|
||||
|
||||
#include <JNIHelp.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <hidl/IServiceManager.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <hwbinder/ProcessState.h>
|
||||
#include <nativehelper/ScopedLocalRef.h>
|
||||
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
using android::AndroidRuntime;
|
||||
|
||||
#define PACKAGE_PATH "android/os"
|
||||
#define CLASS_NAME "HwBinder"
|
||||
#define CLASS_PATH PACKAGE_PATH "/" CLASS_NAME
|
||||
|
||||
namespace android {
|
||||
|
||||
static struct fields_t {
|
||||
jfieldID contextID;
|
||||
jmethodID onTransactID;
|
||||
|
||||
} gFields;
|
||||
|
||||
// static
|
||||
void JHwBinder::InitClass(JNIEnv *env) {
|
||||
ScopedLocalRef<jclass> clazz(
|
||||
env, FindClassOrDie(env, CLASS_PATH));
|
||||
|
||||
gFields.contextID =
|
||||
GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
|
||||
|
||||
gFields.onTransactID =
|
||||
GetMethodIDOrDie(
|
||||
env,
|
||||
clazz.get(),
|
||||
"onTransact",
|
||||
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V");
|
||||
}
|
||||
|
||||
// static
|
||||
sp<JHwBinder> JHwBinder::SetNativeContext(
|
||||
JNIEnv *env, jobject thiz, const sp<JHwBinder> &context) {
|
||||
sp<JHwBinder> old =
|
||||
(JHwBinder *)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<JHwBinder> JHwBinder::GetNativeContext(
|
||||
JNIEnv *env, jobject thiz) {
|
||||
return (JHwBinder *)env->GetLongField(thiz, gFields.contextID);
|
||||
}
|
||||
|
||||
JHwBinder::JHwBinder(JNIEnv *env, jobject thiz) {
|
||||
jclass clazz = env->GetObjectClass(thiz);
|
||||
CHECK(clazz != NULL);
|
||||
|
||||
mClass = (jclass)env->NewGlobalRef(clazz);
|
||||
mObject = env->NewWeakGlobalRef(thiz);
|
||||
}
|
||||
|
||||
JHwBinder::~JHwBinder() {
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
env->DeleteWeakGlobalRef(mObject);
|
||||
mObject = NULL;
|
||||
|
||||
env->DeleteGlobalRef(mClass);
|
||||
mClass = NULL;
|
||||
}
|
||||
|
||||
status_t JHwBinder::onTransact(
|
||||
uint32_t code,
|
||||
const hardware::Parcel &data,
|
||||
hardware::Parcel *reply,
|
||||
uint32_t flags,
|
||||
TransactCallback callback) {
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
ScopedLocalRef<jobject> requestObj(env, JHwParcel::NewObject(env));
|
||||
JHwParcel::GetNativeContext(env, requestObj.get())->setParcel(
|
||||
const_cast<hardware::Parcel *>(&data), false /* assumeOwnership */);
|
||||
|
||||
ScopedLocalRef<jobject> replyObj(env, JHwParcel::NewObject(env));
|
||||
|
||||
sp<JHwParcel> replyContext =
|
||||
JHwParcel::GetNativeContext(env, replyObj.get());
|
||||
|
||||
replyContext->setParcel(reply, false /* assumeOwnership */);
|
||||
replyContext->setTransactCallback(callback);
|
||||
|
||||
env->CallVoidMethod(
|
||||
mObject,
|
||||
gFields.onTransactID,
|
||||
code,
|
||||
requestObj.get(),
|
||||
replyObj.get(),
|
||||
flags);
|
||||
|
||||
status_t err = OK;
|
||||
|
||||
if (!replyContext->wasSent()) {
|
||||
// The implementation never finished the transaction.
|
||||
err = UNKNOWN_ERROR; // XXX special error code instead?
|
||||
|
||||
reply->setDataPosition(0 /* pos */);
|
||||
}
|
||||
|
||||
// Release all temporary storage now that scatter-gather data
|
||||
// has been consolidated, either by calling the TransactCallback,
|
||||
// if wasSent() == true or clearing the reply parcel (setDataOffset above).
|
||||
replyContext->getStorage()->release(env);
|
||||
|
||||
// We cannot permanently pass ownership of "data" and "reply" over to their
|
||||
// Java object wrappers (we don't own them ourselves).
|
||||
|
||||
JHwParcel::GetNativeContext(env, requestObj.get())->setParcel(
|
||||
NULL /* parcel */, false /* assumeOwnership */);
|
||||
|
||||
replyContext->setParcel(
|
||||
NULL /* parcel */, false /* assumeOwnership */);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace android;
|
||||
|
||||
static void releaseNativeContext(void *nativeContext) {
|
||||
sp<JHwBinder> binder = (JHwBinder *)nativeContext;
|
||||
|
||||
if (binder != NULL) {
|
||||
binder->decStrong(NULL /* id */);
|
||||
}
|
||||
}
|
||||
|
||||
static jlong JHwBinder_native_init(JNIEnv *env) {
|
||||
JHwBinder::InitClass(env);
|
||||
|
||||
return reinterpret_cast<jlong>(&releaseNativeContext);
|
||||
}
|
||||
|
||||
static void JHwBinder_native_setup(JNIEnv *env, jobject thiz) {
|
||||
sp<JHwBinder> context = new JHwBinder(env, thiz);
|
||||
|
||||
JHwBinder::SetNativeContext(env, thiz, context);
|
||||
}
|
||||
|
||||
static void JHwBinder_native_transact(
|
||||
JNIEnv * /* env */,
|
||||
jobject /* thiz */,
|
||||
jint /* code */,
|
||||
jobject /* requestObj */,
|
||||
jobject /* replyObj */,
|
||||
jint /* flags */) {
|
||||
CHECK(!"Should not be here");
|
||||
}
|
||||
|
||||
static void JHwBinder_native_registerService(
|
||||
JNIEnv *env, jobject thiz, jstring serviceNameObj) {
|
||||
if (serviceNameObj == NULL) {
|
||||
jniThrowException(env, "java/lang/NullPointerException", NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL);
|
||||
|
||||
if (serviceName == NULL) {
|
||||
return; // XXX exception already pending?
|
||||
}
|
||||
|
||||
const hardware::hidl_version kVersion = hardware::make_hidl_version(1, 0);
|
||||
|
||||
sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz);
|
||||
|
||||
status_t err = hardware::defaultServiceManager()->addService(
|
||||
String16(reinterpret_cast<const char16_t *>(serviceName)),
|
||||
binder,
|
||||
kVersion);
|
||||
|
||||
env->ReleaseStringCritical(serviceNameObj, serviceName);
|
||||
serviceName = NULL;
|
||||
|
||||
if (err == OK) {
|
||||
LOG(INFO) << "Starting thread pool.";
|
||||
::android::hardware::ProcessState::self()->startThreadPool();
|
||||
}
|
||||
|
||||
signalExceptionForError(env, err);
|
||||
}
|
||||
|
||||
static jobject JHwBinder_native_getService(
|
||||
JNIEnv *env, jclass /* clazzObj */, jstring serviceNameObj) {
|
||||
if (serviceNameObj == NULL) {
|
||||
jniThrowException(env, "java/lang/NullPointerException", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL);
|
||||
|
||||
if (serviceName == NULL) {
|
||||
return NULL; // XXX exception already pending?
|
||||
}
|
||||
|
||||
const hardware::hidl_version kVersion = hardware::make_hidl_version(1, 0);
|
||||
|
||||
LOG(INFO) << "looking for service '"
|
||||
<< String8(String16(
|
||||
reinterpret_cast<const char16_t *>(serviceName))).string()
|
||||
<< "'";
|
||||
|
||||
sp<hardware::IBinder> service =
|
||||
hardware::defaultServiceManager()->getService(
|
||||
String16(reinterpret_cast<const char16_t *>(serviceName)),
|
||||
kVersion);
|
||||
|
||||
env->ReleaseStringCritical(serviceNameObj, serviceName);
|
||||
serviceName = NULL;
|
||||
|
||||
if (service == NULL) {
|
||||
signalExceptionForError(env, NAME_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return JHwRemoteBinder::NewObject(env, service);
|
||||
}
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{ "native_init", "()J", (void *)JHwBinder_native_init },
|
||||
{ "native_setup", "()V", (void *)JHwBinder_native_setup },
|
||||
|
||||
{ "transact",
|
||||
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V",
|
||||
(void *)JHwBinder_native_transact },
|
||||
|
||||
{ "registerService", "(Ljava/lang/String;)V",
|
||||
(void *)JHwBinder_native_registerService },
|
||||
|
||||
{ "getService", "(Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;",
|
||||
(void *)JHwBinder_native_getService },
|
||||
};
|
||||
|
||||
namespace android {
|
||||
|
||||
int register_android_os_HwBinder(JNIEnv *env) {
|
||||
return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
60
core/jni/android_os_HwBinder.h
Normal file
60
core/jni/android_os_HwBinder.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_BINDER_H
|
||||
#define _ANDROID_OS_HW_BINDER_H
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <hwbinder/Binder.h>
|
||||
#include <jni.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct JHwBinder : public hardware::BBinder {
|
||||
static void InitClass(JNIEnv *env);
|
||||
|
||||
static sp<JHwBinder> SetNativeContext(
|
||||
JNIEnv *env, jobject thiz, const sp<JHwBinder> &context);
|
||||
|
||||
static sp<JHwBinder> GetNativeContext(JNIEnv *env, jobject thiz);
|
||||
|
||||
JHwBinder(JNIEnv *env, jobject thiz);
|
||||
|
||||
protected:
|
||||
virtual ~JHwBinder();
|
||||
|
||||
virtual status_t onTransact(
|
||||
uint32_t code,
|
||||
const hardware::Parcel &data,
|
||||
hardware::Parcel *reply,
|
||||
uint32_t flags,
|
||||
TransactCallback callback);
|
||||
|
||||
private:
|
||||
jclass mClass;
|
||||
jobject mObject;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(JHwBinder);
|
||||
};
|
||||
|
||||
int register_android_os_HwBinder(JNIEnv *env);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _ANDROID_OS_HW_BINDER_H
|
||||
|
||||
|
||||
452
core/jni/android_os_HwBlob.cpp
Normal file
452
core/jni/android_os_HwBlob.cpp
Normal 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 <hidl/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
|
||||
|
||||
91
core/jni/android_os_HwBlob.h
Normal file
91
core/jni/android_os_HwBlob.h
Normal 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
|
||||
|
||||
1139
core/jni/android_os_HwParcel.cpp
Normal file
1139
core/jni/android_os_HwParcel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
75
core/jni/android_os_HwParcel.h
Normal file
75
core/jni/android_os_HwParcel.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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_PARCEL_H
|
||||
#define ANDROID_OS_HW_PARCEL_H
|
||||
|
||||
#include "hwbinder/EphemeralStorage.h"
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <hwbinder/IBinder.h>
|
||||
#include <hwbinder/Parcel.h>
|
||||
#include <jni.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct JHwParcel : public RefBase {
|
||||
static void InitClass(JNIEnv *env);
|
||||
|
||||
static sp<JHwParcel> SetNativeContext(
|
||||
JNIEnv *env, jobject thiz, const sp<JHwParcel> &context);
|
||||
|
||||
static sp<JHwParcel> GetNativeContext(JNIEnv *env, jobject thiz);
|
||||
|
||||
static jobject NewObject(JNIEnv *env);
|
||||
|
||||
JHwParcel(JNIEnv *env, jobject thiz);
|
||||
|
||||
void setParcel(hardware::Parcel *parcel, bool assumeOwnership);
|
||||
hardware::Parcel *getParcel();
|
||||
|
||||
EphemeralStorage *getStorage();
|
||||
|
||||
void setTransactCallback(::android::hardware::IBinder::TransactCallback cb);
|
||||
|
||||
void send();
|
||||
bool wasSent() const;
|
||||
|
||||
protected:
|
||||
virtual ~JHwParcel();
|
||||
|
||||
private:
|
||||
jclass mClass;
|
||||
jobject mObject;
|
||||
|
||||
hardware::Parcel *mParcel;
|
||||
bool mOwnsParcel;
|
||||
|
||||
EphemeralStorage mStorage;
|
||||
|
||||
::android::hardware::IBinder::TransactCallback mTransactCallback;
|
||||
bool mWasSent;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(JHwParcel);
|
||||
};
|
||||
|
||||
void signalExceptionForError(JNIEnv *env, status_t err);
|
||||
int register_android_os_HwParcel(JNIEnv *env);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_OS_HW_PARCEL_H
|
||||
196
core/jni/android_os_HwRemoteBinder.cpp
Normal file
196
core/jni/android_os_HwRemoteBinder.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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 "JHwRemoteBinder"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "android_os_HwRemoteBinder.h"
|
||||
|
||||
#include "android_os_HwParcel.h"
|
||||
|
||||
#include <JNIHelp.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <hidl/IServiceManager.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <nativehelper/ScopedLocalRef.h>
|
||||
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
using android::AndroidRuntime;
|
||||
|
||||
#define PACKAGE_PATH "android/os"
|
||||
#define CLASS_NAME "HwRemoteBinder"
|
||||
#define CLASS_PATH PACKAGE_PATH "/" CLASS_NAME
|
||||
|
||||
namespace android {
|
||||
|
||||
static struct fields_t {
|
||||
jfieldID contextID;
|
||||
jmethodID constructID;
|
||||
|
||||
} gFields;
|
||||
|
||||
// static
|
||||
void JHwRemoteBinder::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>", "()V");
|
||||
}
|
||||
|
||||
// static
|
||||
sp<JHwRemoteBinder> JHwRemoteBinder::SetNativeContext(
|
||||
JNIEnv *env, jobject thiz, const sp<JHwRemoteBinder> &context) {
|
||||
sp<JHwRemoteBinder> old =
|
||||
(JHwRemoteBinder *)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<JHwRemoteBinder> JHwRemoteBinder::GetNativeContext(
|
||||
JNIEnv *env, jobject thiz) {
|
||||
return (JHwRemoteBinder *)env->GetLongField(thiz, gFields.contextID);
|
||||
}
|
||||
|
||||
// static
|
||||
jobject JHwRemoteBinder::NewObject(
|
||||
JNIEnv *env, const sp<hardware::IBinder> &binder) {
|
||||
ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
|
||||
|
||||
// XXX Have to look up the constructor here because otherwise that static
|
||||
// class initializer isn't called and gFields.constructID is undefined :(
|
||||
|
||||
jmethodID constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "()V");
|
||||
|
||||
jobject obj = env->NewObject(clazz.get(), constructID);
|
||||
JHwRemoteBinder::GetNativeContext(env, obj)->setBinder(binder);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
JHwRemoteBinder::JHwRemoteBinder(
|
||||
JNIEnv *env, jobject thiz, const sp<hardware::IBinder> &binder)
|
||||
: mBinder(binder) {
|
||||
jclass clazz = env->GetObjectClass(thiz);
|
||||
CHECK(clazz != NULL);
|
||||
|
||||
mClass = (jclass)env->NewGlobalRef(clazz);
|
||||
mObject = env->NewWeakGlobalRef(thiz);
|
||||
}
|
||||
|
||||
JHwRemoteBinder::~JHwRemoteBinder() {
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
env->DeleteWeakGlobalRef(mObject);
|
||||
mObject = NULL;
|
||||
|
||||
env->DeleteGlobalRef(mClass);
|
||||
mClass = NULL;
|
||||
}
|
||||
|
||||
sp<hardware::IBinder> JHwRemoteBinder::getBinder() {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
void JHwRemoteBinder::setBinder(const sp<hardware::IBinder> &binder) {
|
||||
mBinder = binder;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace android;
|
||||
|
||||
static void releaseNativeContext(void *nativeContext) {
|
||||
sp<JHwRemoteBinder> binder = (JHwRemoteBinder *)nativeContext;
|
||||
|
||||
if (binder != NULL) {
|
||||
binder->decStrong(NULL /* id */);
|
||||
}
|
||||
}
|
||||
|
||||
static jlong JHwRemoteBinder_native_init(JNIEnv *env) {
|
||||
JHwRemoteBinder::InitClass(env);
|
||||
|
||||
return reinterpret_cast<jlong>(&releaseNativeContext);
|
||||
}
|
||||
|
||||
static void JHwRemoteBinder_native_setup_empty(JNIEnv *env, jobject thiz) {
|
||||
sp<JHwRemoteBinder> context =
|
||||
new JHwRemoteBinder(env, thiz, NULL /* service */);
|
||||
|
||||
JHwRemoteBinder::SetNativeContext(env, thiz, context);
|
||||
}
|
||||
|
||||
static void JHwRemoteBinder_native_transact(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jint code,
|
||||
jobject requestObj,
|
||||
jobject replyObj,
|
||||
jint flags) {
|
||||
sp<hardware::IBinder> binder =
|
||||
JHwRemoteBinder::GetNativeContext(env, thiz)->getBinder();
|
||||
|
||||
if (requestObj == NULL) {
|
||||
jniThrowException(env, "java/lang/NullPointerException", NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
const hardware::Parcel *request =
|
||||
JHwParcel::GetNativeContext(env, requestObj)->getParcel();
|
||||
|
||||
hardware::Parcel *reply =
|
||||
JHwParcel::GetNativeContext(env, replyObj)->getParcel();
|
||||
|
||||
status_t err = binder->transact(code, *request, reply, flags);
|
||||
signalExceptionForError(env, err);
|
||||
}
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{ "native_init", "()J", (void *)JHwRemoteBinder_native_init },
|
||||
|
||||
{ "native_setup_empty", "()V",
|
||||
(void *)JHwRemoteBinder_native_setup_empty },
|
||||
|
||||
{ "transact",
|
||||
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V",
|
||||
(void *)JHwRemoteBinder_native_transact },
|
||||
};
|
||||
|
||||
namespace android {
|
||||
|
||||
int register_android_os_HwRemoteBinder(JNIEnv *env) {
|
||||
return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
60
core/jni/android_os_HwRemoteBinder.h
Normal file
60
core/jni/android_os_HwRemoteBinder.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_REMOTE_BINDER_H
|
||||
#define ANDROID_OS_HW_REMOTE_BINDER_H
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <hwbinder/Binder.h>
|
||||
#include <jni.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct JHwRemoteBinder : public RefBase {
|
||||
static void InitClass(JNIEnv *env);
|
||||
|
||||
static sp<JHwRemoteBinder> SetNativeContext(
|
||||
JNIEnv *env, jobject thiz, const sp<JHwRemoteBinder> &context);
|
||||
|
||||
static sp<JHwRemoteBinder> GetNativeContext(JNIEnv *env, jobject thiz);
|
||||
|
||||
static jobject NewObject(JNIEnv *env, const sp<hardware::IBinder> &binder);
|
||||
|
||||
JHwRemoteBinder(
|
||||
JNIEnv *env, jobject thiz, const sp<hardware::IBinder> &binder);
|
||||
|
||||
sp<hardware::IBinder> getBinder();
|
||||
void setBinder(const sp<hardware::IBinder> &binder);
|
||||
|
||||
protected:
|
||||
virtual ~JHwRemoteBinder();
|
||||
|
||||
private:
|
||||
jclass mClass;
|
||||
jobject mObject;
|
||||
|
||||
sp<hardware::IBinder> mBinder;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(JHwRemoteBinder);
|
||||
};
|
||||
|
||||
int register_android_os_HwRemoteBinder(JNIEnv *env);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_OS_HW_REMOTE_BINDER_H
|
||||
|
||||
178
core/jni/hwbinder/EphemeralStorage.cpp
Normal file
178
core/jni/hwbinder/EphemeralStorage.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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_TAG "EphemeralStorage"
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "EphemeralStorage.h"
|
||||
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
|
||||
namespace android {
|
||||
|
||||
EphemeralStorage::EphemeralStorage() {
|
||||
}
|
||||
|
||||
EphemeralStorage::~EphemeralStorage() {
|
||||
CHECK(mItems.empty())
|
||||
<< "All item storage should have been released by now.";
|
||||
}
|
||||
|
||||
hidl_string *EphemeralStorage::allocStringArray(size_t size) {
|
||||
Item item;
|
||||
item.mType = TYPE_STRING_ARRAY;
|
||||
item.mObj = NULL;
|
||||
item.mPtr = new hidl_string[size];
|
||||
mItems.push_back(item);
|
||||
|
||||
return static_cast<hidl_string *>(item.mPtr);
|
||||
}
|
||||
|
||||
void *EphemeralStorage::allocTemporaryStorage(size_t size) {
|
||||
Item item;
|
||||
item.mType = TYPE_STORAGE;
|
||||
item.mObj = NULL;
|
||||
item.mPtr = malloc(size);
|
||||
mItems.push_back(item);
|
||||
|
||||
return item.mPtr;
|
||||
}
|
||||
|
||||
const hidl_string *EphemeralStorage::allocTemporaryString(
|
||||
JNIEnv *env, jstring stringObj) {
|
||||
jstring obj = (jstring)env->NewGlobalRef(stringObj);
|
||||
const char *val = env->GetStringUTFChars(obj, NULL);
|
||||
|
||||
Item item;
|
||||
item.mType = TYPE_STRING;
|
||||
item.mObj = obj;
|
||||
item.mPtr = (void *)val;
|
||||
mItems.push_back(item);
|
||||
|
||||
hidl_string *s = allocStringArray(1 /* size */);
|
||||
s->setToExternal((char *)val, strlen(val));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#define DEFINE_ALLOC_ARRAY_METHODS(Suffix,Type,NewType) \
|
||||
const Type *EphemeralStorage::allocTemporary ## Suffix ## Array( \
|
||||
JNIEnv *env, Type ## Array arrayObj) { \
|
||||
Type ## Array obj = (Type ## Array)env->NewGlobalRef(arrayObj); \
|
||||
const Type *val = env->Get ## NewType ## ArrayElements(obj, NULL); \
|
||||
\
|
||||
Item item; \
|
||||
item.mType = TYPE_ ## Suffix ## _ARRAY; \
|
||||
item.mObj = obj; \
|
||||
item.mPtr = (void *)val; \
|
||||
mItems.push_back(item); \
|
||||
\
|
||||
return val; \
|
||||
}
|
||||
|
||||
#define DEFINE_ALLOC_VECTOR_METHODS(Suffix,Type,NewType) \
|
||||
const hidl_vec<Type> *EphemeralStorage::allocTemporary ## Suffix ## Vector( \
|
||||
JNIEnv *env, Type ## Array arrayObj) { \
|
||||
Type ## Array obj = (Type ## Array)env->NewGlobalRef(arrayObj); \
|
||||
jsize len = env->GetArrayLength(obj); \
|
||||
const Type *val = env->Get ## NewType ## ArrayElements(obj, NULL); \
|
||||
\
|
||||
Item item; \
|
||||
item.mType = TYPE_ ## Suffix ## _ARRAY; \
|
||||
item.mObj = obj; \
|
||||
item.mPtr = (void *)val; \
|
||||
mItems.push_back(item); \
|
||||
\
|
||||
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; \
|
||||
}
|
||||
|
||||
DEFINE_ALLOC_ARRAY_METHODS(Int8,jbyte,Byte)
|
||||
DEFINE_ALLOC_ARRAY_METHODS(Int16,jshort,Short)
|
||||
DEFINE_ALLOC_ARRAY_METHODS(Int32,jint,Int)
|
||||
DEFINE_ALLOC_ARRAY_METHODS(Int64,jlong,Long)
|
||||
DEFINE_ALLOC_ARRAY_METHODS(Float,jfloat,Float)
|
||||
DEFINE_ALLOC_ARRAY_METHODS(Double,jdouble,Double)
|
||||
|
||||
DEFINE_ALLOC_VECTOR_METHODS(Int8,jbyte,Byte)
|
||||
DEFINE_ALLOC_VECTOR_METHODS(Int16,jshort,Short)
|
||||
DEFINE_ALLOC_VECTOR_METHODS(Int32,jint,Int)
|
||||
DEFINE_ALLOC_VECTOR_METHODS(Int64,jlong,Long)
|
||||
DEFINE_ALLOC_VECTOR_METHODS(Float,jfloat,Float)
|
||||
DEFINE_ALLOC_VECTOR_METHODS(Double,jdouble,Double)
|
||||
|
||||
#define DEFINE_RELEASE_ARRAY_CASE(Suffix,Type,NewType) \
|
||||
case TYPE_ ## Suffix ## _ARRAY: \
|
||||
{ \
|
||||
env->Release ## NewType ## ArrayElements( \
|
||||
(Type ## Array)item.mObj, \
|
||||
(Type *)item.mPtr, \
|
||||
0 /* mode */); \
|
||||
\
|
||||
env->DeleteGlobalRef(item.mObj); \
|
||||
break; \
|
||||
}
|
||||
|
||||
void EphemeralStorage::release(JNIEnv *env) {
|
||||
for (size_t i = mItems.size(); i--;) {
|
||||
const Item &item = mItems[i];
|
||||
|
||||
switch (item.mType) {
|
||||
case TYPE_STRING_ARRAY:
|
||||
{
|
||||
delete[] static_cast<hidl_string *>(item.mPtr);
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_STORAGE:
|
||||
{
|
||||
free(item.mPtr);
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_STRING:
|
||||
{
|
||||
env->ReleaseStringUTFChars(
|
||||
(jstring)item.mObj, (const char *)item.mPtr);
|
||||
|
||||
env->DeleteGlobalRef(item.mObj);
|
||||
break;
|
||||
}
|
||||
|
||||
DEFINE_RELEASE_ARRAY_CASE(Int8,jbyte,Byte)
|
||||
DEFINE_RELEASE_ARRAY_CASE(Int16,jshort,Short)
|
||||
DEFINE_RELEASE_ARRAY_CASE(Int32,jint,Int)
|
||||
DEFINE_RELEASE_ARRAY_CASE(Int64,jlong,Long)
|
||||
DEFINE_RELEASE_ARRAY_CASE(Float,jfloat,Float)
|
||||
DEFINE_RELEASE_ARRAY_CASE(Double,jdouble,Double)
|
||||
|
||||
default:
|
||||
CHECK(!"Should not be here");
|
||||
}
|
||||
}
|
||||
|
||||
mItems.clear();
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
84
core/jni/hwbinder/EphemeralStorage.h
Normal file
84
core/jni/hwbinder/EphemeralStorage.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 EPHEMERAL_STORAGE_H_
|
||||
|
||||
#define EPHEMERAL_STORAGE_H_
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <hidl/HidlSupport.h>
|
||||
#include <jni.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
#define DECLARE_ALLOC_METHODS(Suffix,Type) \
|
||||
const Type *allocTemporary ## Suffix ## Array( \
|
||||
JNIEnv *env, Type ## Array arrayObj); \
|
||||
\
|
||||
const ::android::hardware::hidl_vec<Type> * \
|
||||
allocTemporary ## Suffix ## Vector( \
|
||||
JNIEnv *env, Type ## Array arrayObj);
|
||||
|
||||
struct EphemeralStorage {
|
||||
EphemeralStorage();
|
||||
~EphemeralStorage();
|
||||
|
||||
void release(JNIEnv *env);
|
||||
|
||||
hardware::hidl_string *allocStringArray(size_t size);
|
||||
|
||||
void *allocTemporaryStorage(size_t size);
|
||||
|
||||
const ::android::hardware::hidl_string *allocTemporaryString(
|
||||
JNIEnv *env, jstring stringObj);
|
||||
|
||||
DECLARE_ALLOC_METHODS(Int8,jbyte)
|
||||
DECLARE_ALLOC_METHODS(Int16,jshort)
|
||||
DECLARE_ALLOC_METHODS(Int32,jint)
|
||||
DECLARE_ALLOC_METHODS(Int64,jlong)
|
||||
DECLARE_ALLOC_METHODS(Float,jfloat)
|
||||
DECLARE_ALLOC_METHODS(Double,jdouble)
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
TYPE_STRING_ARRAY,
|
||||
TYPE_STORAGE,
|
||||
TYPE_STRING,
|
||||
TYPE_Int8_ARRAY,
|
||||
TYPE_Int16_ARRAY,
|
||||
TYPE_Int32_ARRAY,
|
||||
TYPE_Int64_ARRAY,
|
||||
TYPE_Float_ARRAY,
|
||||
TYPE_Double_ARRAY,
|
||||
};
|
||||
|
||||
struct Item {
|
||||
Type mType;
|
||||
jobject mObj;
|
||||
void *mPtr;
|
||||
};
|
||||
|
||||
Vector<Item> mItems;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EphemeralStorage);
|
||||
};
|
||||
|
||||
#undef DECLARE_ALLOC_METHODS
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // EPHEMERAL_STORAGE_H_
|
||||
Reference in New Issue
Block a user