diff options
| -rw-r--r-- | core/java/android/os/HidlSupport.java | 23 | ||||
| -rw-r--r-- | core/java/android/os/HwRemoteBinder.java | 5 | ||||
| -rw-r--r-- | core/jni/android_os_HwRemoteBinder.cpp | 49 |
3 files changed, 76 insertions, 1 deletions
diff --git a/core/java/android/os/HidlSupport.java b/core/java/android/os/HidlSupport.java index 7dec4d724f15..3544ea1e03e3 100644 --- a/core/java/android/os/HidlSupport.java +++ b/core/java/android/os/HidlSupport.java @@ -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()); + } } diff --git a/core/java/android/os/HwRemoteBinder.java b/core/java/android/os/HwRemoteBinder.java index 2f89ce6270be..a07e42c720c5 100644 --- a/core/java/android/os/HwRemoteBinder.java +++ b/core/java/android/os/HwRemoteBinder.java @@ -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(); } diff --git a/core/jni/android_os_HwRemoteBinder.cpp b/core/jni/android_os_HwRemoteBinder.cpp index cf59a56a13dc..ca5e1e45dcdc 100644 --- a/core/jni/android_os_HwRemoteBinder.cpp +++ b/core/jni/android_os_HwRemoteBinder.cpp @@ -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 { |