Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 762f27c6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Allow equality checking and hash for HIDL interface proxies."

parents 3a16db62 73b6c27a
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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());
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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();
}
+48 −1
Original line number Diff line number Diff line
@@ -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 {