Merge "Allow equality checking and hash for HIDL interface proxies."
am: 762f27c6a2
Change-Id: Ia6ebb45cd2e7778483df3c191b3f0d175588e3fc
This commit is contained in:
@@ -156,4 +156,27 @@ public class HidlSupport {
|
||||
// Should not reach here.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that two interfaces are equal. This is the Java equivalent to C++
|
||||
* interfacesEqual function.
|
||||
* This essentially calls .equals on the internal binder objects (via Binder()).
|
||||
* - If both interfaces are proxies, asBinder() returns a {@link HwRemoteBinder}
|
||||
* object, and they are compared in {@link HwRemoteBinder#equals}.
|
||||
* - If both interfaces are stubs, asBinder() returns the object itself. By default,
|
||||
* auto-generated IFoo.Stub does not override equals(), but an implementation can
|
||||
* optionally override it, and {@code interfacesEqual} will use it here.
|
||||
*/
|
||||
public static boolean interfacesEqual(IHwInterface lft, Object rgt) {
|
||||
if (lft == rgt) {
|
||||
return true;
|
||||
}
|
||||
if (lft == null || rgt == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(rgt instanceof IHwInterface)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(lft.asBinder(), ((IHwInterface) rgt).asBinder());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,4 +63,9 @@ public class HwRemoteBinder implements IHwBinder {
|
||||
}
|
||||
|
||||
private long mNativeContext;
|
||||
|
||||
@Override
|
||||
public final native boolean equals(Object other);
|
||||
@Override
|
||||
public final native int hashCode();
|
||||
}
|
||||
|
||||
@@ -22,9 +22,13 @@
|
||||
|
||||
#include "android_os_HwParcel.h"
|
||||
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <android/hidl/base/1.0/IBase.h>
|
||||
#include <android/hidl/base/1.0/BpHwBase.h>
|
||||
#include <android/hidl/base/1.0/BnHwBase.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include <nativehelper/ScopedLocalRef.h>
|
||||
|
||||
@@ -413,6 +417,44 @@ static jboolean JHwRemoteBinder_unlinkToDeath(JNIEnv* env, jobject thiz,
|
||||
return res;
|
||||
}
|
||||
|
||||
static sp<hidl::base::V1_0::IBase> toIBase(JNIEnv* env, jclass hwRemoteBinderClazz, jobject jbinder)
|
||||
{
|
||||
if (jbinder == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!env->IsInstanceOf(jbinder, hwRemoteBinderClazz)) {
|
||||
return nullptr;
|
||||
}
|
||||
sp<JHwRemoteBinder> context = JHwRemoteBinder::GetNativeContext(env, jbinder);
|
||||
sp<hardware::IBinder> cbinder = context->getBinder();
|
||||
return hardware::fromBinder<hidl::base::V1_0::IBase, hidl::base::V1_0::BpHwBase,
|
||||
hidl::base::V1_0::BnHwBase>(cbinder);
|
||||
}
|
||||
|
||||
// equals iff other is also a non-null android.os.HwRemoteBinder object
|
||||
// and getBinder() returns the same object.
|
||||
// In particular, if other is an android.os.HwBinder object (for stubs) then
|
||||
// it returns false.
|
||||
static jboolean JHwRemoteBinder_equals(JNIEnv* env, jobject thiz, jobject other)
|
||||
{
|
||||
if (env->IsSameObject(thiz, other)) {
|
||||
return true;
|
||||
}
|
||||
if (other == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
|
||||
|
||||
return hardware::interfacesEqual(toIBase(env, clazz.get(), thiz), toIBase(env, clazz.get(), other));
|
||||
}
|
||||
|
||||
static jint JHwRemoteBinder_hashCode(JNIEnv* env, jobject thiz) {
|
||||
jlong longHash = reinterpret_cast<jlong>(
|
||||
JHwRemoteBinder::GetNativeContext(env, thiz)->getBinder().get());
|
||||
return static_cast<jint>(longHash ^ (longHash >> 32)); // See Long.hashCode()
|
||||
}
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{ "native_init", "()J", (void *)JHwRemoteBinder_native_init },
|
||||
|
||||
@@ -430,6 +472,11 @@ static JNINativeMethod gMethods[] = {
|
||||
{"unlinkToDeath",
|
||||
"(Landroid/os/IHwBinder$DeathRecipient;)Z",
|
||||
(void*)JHwRemoteBinder_unlinkToDeath},
|
||||
|
||||
{"equals", "(Ljava/lang/Object;)Z",
|
||||
(void*)JHwRemoteBinder_equals},
|
||||
|
||||
{"hashCode", "()I", (void*)JHwRemoteBinder_hashCode},
|
||||
};
|
||||
|
||||
namespace android {
|
||||
|
||||
Reference in New Issue
Block a user