Merge changes from topic 'hidl_gen_fix'
am: cbab402a94

Change-Id: Ib6f643b95701bb349b2a5dcce7b4ed8717b09ba8
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";
diff --git a/generateJava.cpp b/generateJava.cpp
index 36cef4e..3d6e781 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -139,8 +139,6 @@
 
     out << "package " << mPackage.javaPackage() << ";\n\n";
 
-    out << "import android.os.RemoteException;\n\n";
-
     out.setNamespace(mPackage.javaPackage() + ".");
 
     const Interface *superType = iface->superType();
@@ -199,7 +197,7 @@
 
     out << "public static "
         << ifaceName
-        << " getService(String serviceName) throws RemoteException {\n";
+        << " getService(String serviceName) throws android.os.RemoteException {\n";
 
     out.indent();
 
@@ -215,7 +213,7 @@
 
     out << "public static "
         << ifaceName
-        << " getService() throws RemoteException {\n";
+        << " getService() throws android.os.RemoteException {\n";
 
     out.indent();
 
@@ -280,7 +278,7 @@
 
         out << ")\n";
         out.indent();
-        out << "throws RemoteException;\n";
+        out << "throws android.os.RemoteException;\n";
         out.unindent();
     }
 
@@ -308,7 +306,7 @@
     out.block([&] {
         out.sTry([&] {
             out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
-        }).sCatch("RemoteException ex", [&] {
+        }).sCatch("android.os.RemoteException ex", [&] {
             out << "/* ignored; handled below. */\n";
         }).endl();
         out << "return \"[class or subclass of \" + "
@@ -357,7 +355,7 @@
         out << ")\n";
         out.indent();
         out.indent();
-        out << "throws RemoteException {\n";
+        out << "throws android.os.RemoteException {\n";
         out.unindent();
 
         if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
@@ -497,7 +495,7 @@
     out.unindent();
     out << "}\n\n";
 
-    out << "public void registerAsService(String serviceName) throws RemoteException {\n";
+    out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
     out.indent();
 
     out << "registerService(serviceName);\n";
@@ -518,7 +516,7 @@
         << "int _hidl_flags)\n";
     out.indent();
     out.indent();
-    out << "throws RemoteException {\n";
+    out << "throws android.os.RemoteException {\n";
     out.unindent();
 
     out << "switch (_hidl_code) {\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 c7b5951..87c4676 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
@@ -22,6 +22,7 @@
 import android.hardware.tests.baz.V1_0.IBazCallback;
 import android.os.HwBinder;
 import android.os.RemoteException;
+import android.os.HidlSupport;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -96,6 +97,10 @@
         throw new RuntimeException();
     }
 
+    private void ExpectFalse(boolean x) {
+        ExpectTrue(!x);
+    }
+
     private void Expect(String result, String s) {
         if (result.equals(s)) {
             return;
@@ -174,7 +179,60 @@
         return "positively huge!";
     }
 
+    private void ExpectDeepEq(Object l, Object r) {
+        ExpectTrue(HidlSupport.deepEquals(l, r));
+        ExpectTrue(HidlSupport.deepHashCode(l) == HidlSupport.deepHashCode(r));
+    }
+
+    private void ExpectDeepNe(Object l, Object r) {
+        ExpectTrue(!HidlSupport.deepEquals(l, r));
+    }
+
     private void client() throws RemoteException {
+
+        ExpectDeepEq(null, null);
+        ExpectDeepNe(null, new String());
+        ExpectDeepNe(new String(), null);
+        ExpectDeepEq(new String(), new String());
+        ExpectDeepEq("hey", "hey");
+
+        ExpectDeepEq(new int[]{1,2}, new int[]{1,2});
+        ExpectDeepNe(new int[]{1,2}, new int[]{1,3});
+        ExpectDeepNe(new int[]{1,2}, new int[]{1,2,3});
+        ExpectDeepEq(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,4}});
+        ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,5}});
+        ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2,3},{4,5,6}});
+        ExpectDeepNe(new int[][]{{1,2},{3,4}}, new int[][]{{1,2},{3,4,5}});
+
+        ExpectDeepEq(new Integer[]{1,2}, new Integer[]{1,2});
+        ExpectDeepNe(new Integer[]{1,2}, new Integer[]{1,3});
+        ExpectDeepNe(new Integer[]{1,2}, new Integer[]{1,2,3});
+        ExpectDeepEq(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,4}});
+        ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,5}});
+        ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2,3},{4,5,6}});
+        ExpectDeepNe(new Integer[][]{{1,2},{3,4}}, new Integer[][]{{1,2},{3,4,5}});
+
+        ExpectDeepEq(new ArrayList(Arrays.asList(1, 2)),
+                     new ArrayList(Arrays.asList(1, 2)));
+        ExpectDeepNe(new ArrayList(Arrays.asList(1, 2)),
+                     new ArrayList(Arrays.asList(1, 2, 3)));
+
+        ExpectDeepEq(new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})),
+                     new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})));
+        ExpectDeepNe(new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,4})),
+                     new ArrayList(Arrays.asList(new int[]{1,2}, new int[]{3,5})));
+
+        ExpectDeepEq(new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})),
+                     new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})));
+        ExpectDeepNe(new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,4})),
+                     new ArrayList(Arrays.asList(new Integer[]{1,2}, new Integer[]{3,5})));
+
+        ExpectDeepEq(new ArrayList[]{new ArrayList(Arrays.asList(1,2)),
+                                     new ArrayList(Arrays.asList(3,4))},
+                     new ArrayList[]{new ArrayList(Arrays.asList(1,2)),
+                                     new ArrayList(Arrays.asList(3,4))});
+
+
         {
             // Test access through base interface binder.
             IBase baseProxy = IBase.getService("baz");
@@ -312,13 +370,7 @@
             }
 
             IBase.VectorOfArray out = proxy.someMethodWithVectorOfArray(in);
-            /*
-             * TODO(b/36454147) Switch to .equals once the bug is fixed.
-             */
-            ExpectTrue(expectedOut.addresses.size() == out.addresses.size());
-            for  (int i = 0; i < n; ++i) {
-                ExpectTrue(java.util.Objects.deepEquals(out.addresses.get(i), expectedOut.addresses.get(i)));
-            }
+            ExpectTrue(out.equals(expectedOut));
         }
 
         {