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

Commit 7dbaf899 authored by Yifan Hong's avatar Yifan Hong Committed by android-build-merger
Browse files

Merge "Allow equality checking and hash for HIDL interface proxies." am: 762f27c6 am: 0134fd15

am: ddfee6b1

Change-Id: I70c7fb09397cf9b483ed648f1516158c6c431475
parents c76ca488 ddfee6b1
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 {