Emit equals and hashcode for auto-generated Java code.
Test: hidl_test_java
Bug: 32834072
Change-Id: I660852b7d76f79d41b93c9986e4c1188c02ba4a6
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 5f3dd5a..6527f86 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -16,6 +16,7 @@
#include "CompoundType.h"
+#include "ArrayType.h"
#include "VectorType.h"
#include <hidl-util/Formatter.h>
#include <android-base/logging.h>
@@ -489,6 +490,50 @@
out << "\n";
}
+ ////////////////////////////////////////////////////////////////////////////
+
+ if (canCheckEquality()) {
+ out << "public final boolean equals(" << localName() << " other) ";
+ out.block([&] {
+ for (const auto &field : *mFields) {
+ std::string condition = field->type().isScalar()
+ ? "this." + field->name() + " != other." + field->name()
+ : ("!java.util.Objects.deepEquals(this." + field->name()
+ + ", other." + field->name() + ")");
+ out.sIf(condition, [&] {
+ out << "return false;\n";
+ }).endl();
+ }
+ out << "return true;\n";
+ }).endl().endl();
+
+ out << "public final int hashCode() ";
+ out.block([&] {
+ out << "return java.util.Objects.hash(";
+ bool first = true;
+ for (const auto &field : *mFields) {
+ if (!first) {
+ out << ", ";
+ }
+ first = false;
+ if (field->type().isArray()) {
+ const ArrayType &type = static_cast<const ArrayType &>(field->type());
+ if (type.countDimensions() == 1 &&
+ type.getElementType()->resolveToScalarType() != nullptr) {
+ out << "java.util.Arrays.hashCode(this." << field->name() << ")";
+ } else {
+ out << "java.util.Arrays.deepHashCode(this." << field->name() << ")";
+ }
+ } else {
+ out << "this." << field->name();
+ }
+ }
+ out << ");\n";
+ }).endl().endl();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+
out << "public final void readFromParcel(android.os.HwParcel parcel) {\n";
out.indent();
out << "android.os.HwBlob blob = parcel.readBuffer();\n";
diff --git a/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java b/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
index e80584a..0050045 100644
--- a/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
+++ b/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
@@ -736,6 +736,20 @@
System.gc();
proxy.iAmFreeNow();
+ {
+ IBaz.T t1 = new IBaz.T();
+ IBaz.T t2 = new IBaz.T();
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 3; j++) {
+ t1.matrix5x3[i][j] = t2.matrix5x3[i][j] = (i + 1) * (j + 1);
+ }
+ }
+ ExpectTrue(t1.equals(t2));
+ ExpectTrue(t1.hashCode() == t2.hashCode());
+ t2.matrix5x3[4][2] = -60;
+ ExpectTrue(!t1.equals(t2));
+ }
+
// --- DEATH RECIPIENT TESTING ---
// This must always be done last, since it will kill the native server process
HidlDeathRecipient recipient1 = new HidlDeathRecipient();
@@ -755,6 +769,7 @@
ExpectTrue(!recipient2.waitUntilServiceDied(2000 /*timeoutMillis*/));
ExpectTrue(recipient1.cookieMatches(cookie1));
Log.d(TAG, "OK, exiting");
+
}
class Baz extends IBaz.Stub {