Fix .equals in Java does not handle edge cases.

The old .equals code uses Objects.deepEquals,
which does not handle for, e.g. ArrayList<byte[]>.
Create our own recursive HidlSupport.deepEquals
and deepHashCode method to handle these edge cases.

Bug: 36454147
Test: hidl_test_java
Change-Id: I58d86c163e81899da1db266b2589b8652df1e2c1
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 332bada..19b1896 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -582,15 +582,15 @@
             out.sIf("otherObject == null", [&] {
                 out << "return false;\n";
             }).endl();
-            // Class is final, so we only need to check instanceof, not getClass
-            out.sIf("!(otherObject instanceof " + fullJavaName() + ")", [&] {
+            // Though class is final, we use getClass instead of instanceof to be explicit.
+            out.sIf("otherObject.getClass() != " + fullJavaName() + ".class", [&] {
                 out << "return false;\n";
             }).endl();
             out << fullJavaName() << " other = (" << fullJavaName() << ")otherObject;\n";
             for (const auto &field : *mFields) {
-                std::string condition = field->type().isScalar()
+                std::string condition = (field->type().isScalar() || field->type().isEnum())
                     ? "this." + field->name() + " != other." + field->name()
-                    : ("!java.util.Objects.deepEquals(this." + field->name()
+                    : ("!android.os.HidlSupport.deepEquals(this." + field->name()
                             + ", other." + field->name() + ")");
                 out.sIf(condition, [&] {
                     out << "return false;\n";
@@ -609,17 +609,7 @@
                         out << ", \n";
                     }
                     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 << "android.os.HidlSupport.deepHashCode(this." << field->name() << ")";
                 }
             });
             out << ");\n";