AW: use correct ClassLoader in dupeMethod

This fixes an issue with the support library where we would sometimes
create an InvocationHandler and look up methods using the wrong
ClassLoader. This ensures we always use the correct ClassLoader.

dupeMethod() is only used here, so it's safe to change the signature.

See the crbug for more information.

Bug: 826988
Test: Manual, did this in my demo CL at http://crrev/c/965883
Change-Id: I7ca7bb90aec81a6a30ce4d6393cf40ee54d40c19
Reviewed-on: https://chromium-review.googlesource.com/985631
Reviewed-by: Richard Coles <torne@chromium.org>
Commit-Queue: Nate Fischer <ntfschr@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#546961}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: c6aed4c0fe3d8eeb3ae7f2bdd32cc6433cdf929c
diff --git a/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java b/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
index 5a772c5..51c78ed 100644
--- a/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
+++ b/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
@@ -16,13 +16,14 @@
  */
 public class BoundaryInterfaceReflectionUtil {
     /**
-     * Utility method for fetching a method from the current classloader, with the same signature
+     * Utility method for fetching a method from {@param delegateLoader}, with the same signature
      * (package + class + method name + parameters) as a given method defined in another
      * classloader.
      */
-    public static Method dupeMethod(Method method)
+    public static Method dupeMethod(Method method, ClassLoader delegateLoader)
             throws ClassNotFoundException, NoSuchMethodException {
-        Class<?> declaringClass = Class.forName(method.getDeclaringClass().getName());
+        Class<?> declaringClass =
+                Class.forName(method.getDeclaringClass().getName(), true, delegateLoader);
         Class[] otherSideParameterClasses = method.getParameterTypes();
         Class[] parameterClasses = new Class[otherSideParameterClasses.length];
         for (int n = 0; n < parameterClasses.length; n++) {
@@ -30,7 +31,9 @@
             // Primitive classes are shared between the classloaders - so we can use the same
             // primitive class declarations on either side. Non-primitive classes must be looked up
             // by name.
-            parameterClasses[n] = clazz.isPrimitive() ? clazz : Class.forName(clazz.getName());
+            parameterClasses[n] = clazz.isPrimitive()
+                    ? clazz
+                    : Class.forName(clazz.getName(), true, delegateLoader);
         }
         return declaringClass.getDeclaredMethod(method.getName(), parameterClasses);
     }
@@ -53,11 +56,12 @@
      */
     @TargetApi(Build.VERSION_CODES.KITKAT)
     public static InvocationHandler createInvocationHandlerFor(final Object delegate) {
+        final ClassLoader delegateLoader = delegate.getClass().getClassLoader();
         return new InvocationHandler() {
             @Override
             public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                 try {
-                    return dupeMethod(method).invoke(delegate, objects);
+                    return dupeMethod(method, delegateLoader).invoke(delegate, objects);
                 } catch (InvocationTargetException e) {
                     // If something went wrong, ensure we throw the original exception.
                     throw e.getTargetException();