ART: Add GetMethodDeclaringClass

Support GetMethodDeclaringClass to retrieve the declaring class
of a JNI method.

Extend test 910. Also cover proxies.

Bug: 31684812
Test: m test-art-host-run-test-910-methods
Change-Id: I8508f96f88692e540ef53f693ff85590b7553f19
diff --git a/test/910-methods/src/Main.java b/test/910-methods/src/Main.java
index 1af30ba..d8c4627 100644
--- a/test/910-methods/src/Main.java
+++ b/test/910-methods/src/Main.java
@@ -15,6 +15,7 @@
  */
 
 import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.util.Arrays;
 
 public class Main {
@@ -29,15 +30,40 @@
     testMethod("java.lang.String", "charAt", int.class);
     testMethod("java.lang.Math", "sqrt", double.class);
     testMethod("java.util.List", "add", Object.class);
+
+    testMethod(getProxyClass(), "run");
+  }
+
+  private static Class<?> proxyClass = null;
+
+  private static Class<?> getProxyClass() throws Exception {
+    if (proxyClass != null) {
+      return proxyClass;
+    }
+
+    proxyClass = Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Runnable.class });
+    return proxyClass;
   }
 
   private static void testMethod(String className, String methodName, Class<?>... types)
       throws Exception {
     Class<?> base = Class.forName(className);
+    testMethod(base, methodName, types);
+  }
+
+  private static void testMethod(Class<?> base, String methodName, Class<?>... types)
+      throws Exception {
     Method m = base.getDeclaredMethod(methodName, types);
     String[] result = getMethodName(m);
     System.out.println(Arrays.toString(result));
+
+    Class<?> declClass = getMethodDeclaringClass(m);
+    if (base != declClass) {
+      throw new RuntimeException("Declaring class not equal: " + base + " vs " + declClass);
+    }
+    System.out.println(declClass);
   }
 
   private static native String[] getMethodName(Method m);
+  private static native Class<?> getMethodDeclaringClass(Method m);
 }