Home | History | Annotate | Download | only in reflect
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.lang.reflect;
     28 
     29 
     30 import dalvik.annotation.optimization.FastNative;
     31 import java.lang.ref.Reference;
     32 import java.lang.ref.WeakReference;
     33 import java.security.Permission;
     34 import java.security.PrivilegedAction;
     35 import java.util.ArrayList;
     36 import java.util.Arrays;
     37 import java.util.Arrays;
     38 import java.util.Collections;
     39 import java.util.Comparator;
     40 import java.util.HashMap;
     41 import java.util.HashSet;
     42 import java.util.IdentityHashMap;
     43 import java.util.List;
     44 import java.util.Map;
     45 import java.util.Objects;
     46 import java.util.Set;
     47 import java.util.WeakHashMap;
     48 import java.util.concurrent.atomic.AtomicLong;
     49 import java.util.function.BiFunction;
     50 import libcore.util.EmptyArray;
     51 import sun.reflect.CallerSensitive;
     52 import sun.reflect.misc.ReflectUtil;
     53 import sun.security.util.SecurityConstants;
     54 
     55 /**
     56  * {@code Proxy} provides static methods for creating dynamic proxy
     57  * classes and instances, and it is also the superclass of all
     58  * dynamic proxy classes created by those methods.
     59  *
     60  * <p>To create a proxy for some interface {@code Foo}:
     61  * <pre>
     62  *     InvocationHandler handler = new MyInvocationHandler(...);
     63  *     Class&lt;?&gt; proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
     64  *     Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
     65  *                     newInstance(handler);
     66  * </pre>
     67  * or more simply:
     68  * <pre>
     69  *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
     70  *                                          new Class&lt;?&gt;[] { Foo.class },
     71  *                                          handler);
     72  * </pre>
     73  *
     74  * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
     75  * class</i> below) is a class that implements a list of interfaces
     76  * specified at runtime when the class is created, with behavior as
     77  * described below.
     78  *
     79  * A <i>proxy interface</i> is such an interface that is implemented
     80  * by a proxy class.
     81  *
     82  * A <i>proxy instance</i> is an instance of a proxy class.
     83  *
     84  * Each proxy instance has an associated <i>invocation handler</i>
     85  * object, which implements the interface {@link InvocationHandler}.
     86  * A method invocation on a proxy instance through one of its proxy
     87  * interfaces will be dispatched to the {@link InvocationHandler#invoke
     88  * invoke} method of the instance's invocation handler, passing the proxy
     89  * instance, a {@code java.lang.reflect.Method} object identifying
     90  * the method that was invoked, and an array of type {@code Object}
     91  * containing the arguments.  The invocation handler processes the
     92  * encoded method invocation as appropriate and the result that it
     93  * returns will be returned as the result of the method invocation on
     94  * the proxy instance.
     95  *
     96  * <p>A proxy class has the following properties:
     97  *
     98  * <ul>
     99  * <li>Proxy classes are <em>public, final, and not abstract</em> if
    100  * all proxy interfaces are public.</li>
    101  *
    102  * <li>Proxy classes are <em>non-public, final, and not abstract</em> if
    103  * any of the proxy interfaces is non-public.</li>
    104  *
    105  * <li>The unqualified name of a proxy class is unspecified.  The space
    106  * of class names that begin with the string {@code "$Proxy"}
    107  * should be, however, reserved for proxy classes.
    108  *
    109  * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
    110  *
    111  * <li>A proxy class implements exactly the interfaces specified at its
    112  * creation, in the same order.
    113  *
    114  * <li>If a proxy class implements a non-public interface, then it will
    115  * be defined in the same package as that interface.  Otherwise, the
    116  * package of a proxy class is also unspecified.  Note that package
    117  * sealing will not prevent a proxy class from being successfully defined
    118  * in a particular package at runtime, and neither will classes already
    119  * defined by the same class loader and the same package with particular
    120  * signers.
    121  *
    122  * <li>Since a proxy class implements all of the interfaces specified at
    123  * its creation, invoking {@code getInterfaces} on its
    124  * {@code Class} object will return an array containing the same
    125  * list of interfaces (in the order specified at its creation), invoking
    126  * {@code getMethods} on its {@code Class} object will return
    127  * an array of {@code Method} objects that include all of the
    128  * methods in those interfaces, and invoking {@code getMethod} will
    129  * find methods in the proxy interfaces as would be expected.
    130  *
    131  * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
    132  * return true if it is passed a proxy class-- a class returned by
    133  * {@code Proxy.getProxyClass} or the class of an object returned by
    134  * {@code Proxy.newProxyInstance}-- and false otherwise.
    135  *
    136  * <li>The {@code java.security.ProtectionDomain} of a proxy class
    137  * is the same as that of system classes loaded by the bootstrap class
    138  * loader, such as {@code java.lang.Object}, because the code for a
    139  * proxy class is generated by trusted system code.  This protection
    140  * domain will typically be granted
    141  * {@code java.security.AllPermission}.
    142  *
    143  * <li>Each proxy class has one public constructor that takes one argument,
    144  * an implementation of the interface {@link InvocationHandler}, to set
    145  * the invocation handler for a proxy instance.  Rather than having to use
    146  * the reflection API to access the public constructor, a proxy instance
    147  * can be also be created by calling the {@link Proxy#newProxyInstance
    148  * Proxy.newProxyInstance} method, which combines the actions of calling
    149  * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
    150  * constructor with an invocation handler.
    151  * </ul>
    152  *
    153  * <p>A proxy instance has the following properties:
    154  *
    155  * <ul>
    156  * <li>Given a proxy instance {@code proxy} and one of the
    157  * interfaces implemented by its proxy class {@code Foo}, the
    158  * following expression will return true:
    159  * <pre>
    160  *     {@code proxy instanceof Foo}
    161  * </pre>
    162  * and the following cast operation will succeed (rather than throwing
    163  * a {@code ClassCastException}):
    164  * <pre>
    165  *     {@code (Foo) proxy}
    166  * </pre>
    167  *
    168  * <li>Each proxy instance has an associated invocation handler, the one
    169  * that was passed to its constructor.  The static
    170  * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
    171  * will return the invocation handler associated with the proxy instance
    172  * passed as its argument.
    173  *
    174  * <li>An interface method invocation on a proxy instance will be
    175  * encoded and dispatched to the invocation handler's {@link
    176  * InvocationHandler#invoke invoke} method as described in the
    177  * documentation for that method.
    178  *
    179  * <li>An invocation of the {@code hashCode},
    180  * {@code equals}, or {@code toString} methods declared in
    181  * {@code java.lang.Object} on a proxy instance will be encoded and
    182  * dispatched to the invocation handler's {@code invoke} method in
    183  * the same manner as interface method invocations are encoded and
    184  * dispatched, as described above.  The declaring class of the
    185  * {@code Method} object passed to {@code invoke} will be
    186  * {@code java.lang.Object}.  Other public methods of a proxy
    187  * instance inherited from {@code java.lang.Object} are not
    188  * overridden by a proxy class, so invocations of those methods behave
    189  * like they do for instances of {@code java.lang.Object}.
    190  * </ul>
    191  *
    192  * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
    193  *
    194  * <p>When two or more interfaces of a proxy class contain a method with
    195  * the same name and parameter signature, the order of the proxy class's
    196  * interfaces becomes significant.  When such a <i>duplicate method</i>
    197  * is invoked on a proxy instance, the {@code Method} object passed
    198  * to the invocation handler will not necessarily be the one whose
    199  * declaring class is assignable from the reference type of the interface
    200  * that the proxy's method was invoked through.  This limitation exists
    201  * because the corresponding method implementation in the generated proxy
    202  * class cannot determine which interface it was invoked through.
    203  * Therefore, when a duplicate method is invoked on a proxy instance,
    204  * the {@code Method} object for the method in the foremost interface
    205  * that contains the method (either directly or inherited through a
    206  * superinterface) in the proxy class's list of interfaces is passed to
    207  * the invocation handler's {@code invoke} method, regardless of the
    208  * reference type through which the method invocation occurred.
    209  *
    210  * <p>If a proxy interface contains a method with the same name and
    211  * parameter signature as the {@code hashCode}, {@code equals},
    212  * or {@code toString} methods of {@code java.lang.Object},
    213  * when such a method is invoked on a proxy instance, the
    214  * {@code Method} object passed to the invocation handler will have
    215  * {@code java.lang.Object} as its declaring class.  In other words,
    216  * the public, non-final methods of {@code java.lang.Object}
    217  * logically precede all of the proxy interfaces for the determination of
    218  * which {@code Method} object to pass to the invocation handler.
    219  *
    220  * <p>Note also that when a duplicate method is dispatched to an
    221  * invocation handler, the {@code invoke} method may only throw
    222  * checked exception types that are assignable to one of the exception
    223  * types in the {@code throws} clause of the method in <i>all</i> of
    224  * the proxy interfaces that it can be invoked through.  If the
    225  * {@code invoke} method throws a checked exception that is not
    226  * assignable to any of the exception types declared by the method in one
    227  * of the proxy interfaces that it can be invoked through, then an
    228  * unchecked {@code UndeclaredThrowableException} will be thrown by
    229  * the invocation on the proxy instance.  This restriction means that not
    230  * all of the exception types returned by invoking
    231  * {@code getExceptionTypes} on the {@code Method} object
    232  * passed to the {@code invoke} method can necessarily be thrown
    233  * successfully by the {@code invoke} method.
    234  *
    235  * @author      Peter Jones
    236  * @see         InvocationHandler
    237  * @since       1.3
    238  */
    239 public class Proxy implements java.io.Serializable {
    240 
    241     private static final long serialVersionUID = -2222568056686623797L;
    242 
    243     /** parameter types of a proxy class constructor */
    244     private static final Class<?>[] constructorParams =
    245         { InvocationHandler.class };
    246 
    247     /**
    248      * a cache of proxy classes
    249      */
    250     private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
    251         proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
    252 
    253     /**
    254      * the invocation handler for this proxy instance.
    255      * @serial
    256      */
    257     protected InvocationHandler h;
    258 
    259     /**
    260      * Prohibits instantiation.
    261      */
    262     private Proxy() {
    263     }
    264 
    265     /**
    266      * Constructs a new {@code Proxy} instance from a subclass
    267      * (typically, a dynamic proxy class) with the specified value
    268      * for its invocation handler.
    269      *
    270      * @param  h the invocation handler for this proxy instance
    271      *
    272      * @throws NullPointerException if the given invocation handler, {@code h},
    273      *         is {@code null}.
    274      */
    275     protected Proxy(InvocationHandler h) {
    276         Objects.requireNonNull(h);
    277         this.h = h;
    278     }
    279 
    280     /**
    281      * Returns the {@code java.lang.Class} object for a proxy class
    282      * given a class loader and an array of interfaces.  The proxy class
    283      * will be defined by the specified class loader and will implement
    284      * all of the supplied interfaces.  If any of the given interfaces
    285      * is non-public, the proxy class will be non-public. If a proxy class
    286      * for the same permutation of interfaces has already been defined by the
    287      * class loader, then the existing proxy class will be returned; otherwise,
    288      * a proxy class for those interfaces will be generated dynamically
    289      * and defined by the class loader.
    290      *
    291      * <p>There are several restrictions on the parameters that may be
    292      * passed to {@code Proxy.getProxyClass}:
    293      *
    294      * <ul>
    295      * <li>All of the {@code Class} objects in the
    296      * {@code interfaces} array must represent interfaces, not
    297      * classes or primitive types.
    298      *
    299      * <li>No two elements in the {@code interfaces} array may
    300      * refer to identical {@code Class} objects.
    301      *
    302      * <li>All of the interface types must be visible by name through the
    303      * specified class loader.  In other words, for class loader
    304      * {@code cl} and every interface {@code i}, the following
    305      * expression must be true:
    306      * <pre>
    307      *     Class.forName(i.getName(), false, cl) == i
    308      * </pre>
    309      *
    310      * <li>All non-public interfaces must be in the same package;
    311      * otherwise, it would not be possible for the proxy class to
    312      * implement all of the interfaces, regardless of what package it is
    313      * defined in.
    314      *
    315      * <li>For any set of member methods of the specified interfaces
    316      * that have the same signature:
    317      * <ul>
    318      * <li>If the return type of any of the methods is a primitive
    319      * type or void, then all of the methods must have that same
    320      * return type.
    321      * <li>Otherwise, one of the methods must have a return type that
    322      * is assignable to all of the return types of the rest of the
    323      * methods.
    324      * </ul>
    325      *
    326      * <li>The resulting proxy class must not exceed any limits imposed
    327      * on classes by the virtual machine.  For example, the VM may limit
    328      * the number of interfaces that a class may implement to 65535; in
    329      * that case, the size of the {@code interfaces} array must not
    330      * exceed 65535.
    331      * </ul>
    332      *
    333      * <p>If any of these restrictions are violated,
    334      * {@code Proxy.getProxyClass} will throw an
    335      * {@code IllegalArgumentException}.  If the {@code interfaces}
    336      * array argument or any of its elements are {@code null}, a
    337      * {@code NullPointerException} will be thrown.
    338      *
    339      * <p>Note that the order of the specified proxy interfaces is
    340      * significant: two requests for a proxy class with the same combination
    341      * of interfaces but in a different order will result in two distinct
    342      * proxy classes.
    343      *
    344      * @param   loader the class loader to define the proxy class
    345      * @param   interfaces the list of interfaces for the proxy class
    346      *          to implement
    347      * @return  a proxy class that is defined in the specified class loader
    348      *          and that implements the specified interfaces
    349      * @throws  IllegalArgumentException if any of the restrictions on the
    350      *          parameters that may be passed to {@code getProxyClass}
    351      *          are violated
    352      * @throws  SecurityException if a security manager, <em>s</em>, is present
    353      *          and any of the following conditions is met:
    354      *          <ul>
    355      *             <li> the given {@code loader} is {@code null} and
    356      *             the caller's class loader is not {@code null} and the
    357      *             invocation of {@link SecurityManager#checkPermission
    358      *             s.checkPermission} with
    359      *             {@code RuntimePermission("getClassLoader")} permission
    360      *             denies access.</li>
    361      *             <li> for each proxy interface, {@code intf},
    362      *             the caller's class loader is not the same as or an
    363      *             ancestor of the class loader for {@code intf} and
    364      *             invocation of {@link SecurityManager#checkPackageAccess
    365      *             s.checkPackageAccess()} denies access to {@code intf}.</li>
    366      *          </ul>
    367      * @throws  NullPointerException if the {@code interfaces} array
    368      *          argument or any of its elements are {@code null}
    369      */
    370     @CallerSensitive
    371     public static Class<?> getProxyClass(ClassLoader loader,
    372                                          Class<?>... interfaces)
    373         throws IllegalArgumentException
    374     {
    375         // BEGIN Android-changed: Excluded SecurityManager / permission checks.
    376         /*
    377         final Class<?>[] intfs = interfaces.clone();
    378         final SecurityManager sm = System.getSecurityManager();
    379         if (sm != null) {
    380             checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    381         }
    382 
    383         return getProxyClass0(loader, intfs);
    384         */
    385 
    386         return getProxyClass0(loader, interfaces);
    387         // END Android-changed: Excluded SecurityManager / permission checks.
    388     }
    389 
    390     // Android-removed: SecurityManager / permission check code.
    391     /*
    392     /*
    393      * Check permissions required to create a Proxy class.
    394      *
    395      * To define a proxy class, it performs the access checks as in
    396      * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
    397      * 1. "getClassLoader" permission check if loader == null
    398      * 2. checkPackageAccess on the interfaces it implements
    399      *
    400      * To get a constructor and new instance of a proxy class, it performs
    401      * the package access check on the interfaces it implements
    402      * as in Class.getConstructor.
    403      *
    404      * If an interface is non-public, the proxy class must be defined by
    405      * the defining loader of the interface.  If the caller's class loader
    406      * is not the same as the defining loader of the interface, the VM
    407      * will throw IllegalAccessError when the generated proxy class is
    408      * being defined via the defineClass0 method.
    409      *
    410     private static void checkProxyAccess(Class<?> caller,
    411                                          ClassLoader loader,
    412                                          Class<?>... interfaces)
    413     {
    414         SecurityManager sm = System.getSecurityManager();
    415         if (sm != null) {
    416             ClassLoader ccl = caller.getClassLoader();
    417             if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
    418                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
    419             }
    420             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
    421         }
    422     }
    423     */
    424 
    425     /**
    426      * Generate a proxy class.  Must call the checkProxyAccess method
    427      * to perform permission checks before calling this.
    428      */
    429     private static Class<?> getProxyClass0(ClassLoader loader,
    430                                            Class<?>... interfaces) {
    431         if (interfaces.length > 65535) {
    432             throw new IllegalArgumentException("interface limit exceeded");
    433         }
    434 
    435         // If the proxy class defined by the given loader implementing
    436         // the given interfaces exists, this will simply return the cached copy;
    437         // otherwise, it will create the proxy class via the ProxyClassFactory
    438         return proxyClassCache.get(loader, interfaces);
    439     }
    440 
    441     /*
    442      * a key used for proxy class with 0 implemented interfaces
    443      */
    444     private static final Object key0 = new Object();
    445 
    446     /*
    447      * Key1 and Key2 are optimized for the common use of dynamic proxies
    448      * that implement 1 or 2 interfaces.
    449      */
    450 
    451     /*
    452      * a key used for proxy class with 1 implemented interface
    453      */
    454     private static final class Key1 extends WeakReference<Class<?>> {
    455         private final int hash;
    456 
    457         Key1(Class<?> intf) {
    458             super(intf);
    459             this.hash = intf.hashCode();
    460         }
    461 
    462         @Override
    463         public int hashCode() {
    464             return hash;
    465         }
    466 
    467         @Override
    468         public boolean equals(Object obj) {
    469             Class<?> intf;
    470             return this == obj ||
    471                    obj != null &&
    472                    obj.getClass() == Key1.class &&
    473                    (intf = get()) != null &&
    474                    intf == ((Key1) obj).get();
    475         }
    476     }
    477 
    478     /*
    479      * a key used for proxy class with 2 implemented interfaces
    480      */
    481     private static final class Key2 extends WeakReference<Class<?>> {
    482         private final int hash;
    483         private final WeakReference<Class<?>> ref2;
    484 
    485         Key2(Class<?> intf1, Class<?> intf2) {
    486             super(intf1);
    487             hash = 31 * intf1.hashCode() + intf2.hashCode();
    488             ref2 = new WeakReference<Class<?>>(intf2);
    489         }
    490 
    491         @Override
    492         public int hashCode() {
    493             return hash;
    494         }
    495 
    496         @Override
    497         public boolean equals(Object obj) {
    498             Class<?> intf1, intf2;
    499             return this == obj ||
    500                    obj != null &&
    501                    obj.getClass() == Key2.class &&
    502                    (intf1 = get()) != null &&
    503                    intf1 == ((Key2) obj).get() &&
    504                    (intf2 = ref2.get()) != null &&
    505                    intf2 == ((Key2) obj).ref2.get();
    506         }
    507     }
    508 
    509     /*
    510      * a key used for proxy class with any number of implemented interfaces
    511      * (used here for 3 or more only)
    512      */
    513     private static final class KeyX {
    514         private final int hash;
    515         private final WeakReference<Class<?>>[] refs;
    516 
    517         @SuppressWarnings("unchecked")
    518         KeyX(Class<?>[] interfaces) {
    519             hash = Arrays.hashCode(interfaces);
    520             refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
    521             for (int i = 0; i < interfaces.length; i++) {
    522                 refs[i] = new WeakReference<>(interfaces[i]);
    523             }
    524         }
    525 
    526         @Override
    527         public int hashCode() {
    528             return hash;
    529         }
    530 
    531         @Override
    532         public boolean equals(Object obj) {
    533             return this == obj ||
    534                    obj != null &&
    535                    obj.getClass() == KeyX.class &&
    536                    equals(refs, ((KeyX) obj).refs);
    537         }
    538 
    539         private static boolean equals(WeakReference<Class<?>>[] refs1,
    540                                       WeakReference<Class<?>>[] refs2) {
    541             if (refs1.length != refs2.length) {
    542                 return false;
    543             }
    544             for (int i = 0; i < refs1.length; i++) {
    545                 Class<?> intf = refs1[i].get();
    546                 if (intf == null || intf != refs2[i].get()) {
    547                     return false;
    548                 }
    549             }
    550             return true;
    551         }
    552     }
    553 
    554     /**
    555      * A function that maps an array of interfaces to an optimal key where
    556      * Class objects representing interfaces are weakly referenced.
    557      */
    558     private static final class KeyFactory
    559         implements BiFunction<ClassLoader, Class<?>[], Object>
    560     {
    561         @Override
    562         public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
    563             switch (interfaces.length) {
    564                 case 1: return new Key1(interfaces[0]); // the most frequent
    565                 case 2: return new Key2(interfaces[0], interfaces[1]);
    566                 case 0: return key0;
    567                 default: return new KeyX(interfaces);
    568             }
    569         }
    570     }
    571 
    572     // BEGIN Android-changed: How proxies are generated.
    573     /**
    574      * Orders methods by their name, parameters, return type and inheritance relationship.
    575      *
    576      * @hide
    577      */
    578     private static final Comparator<Method> ORDER_BY_SIGNATURE_AND_SUBTYPE = new Comparator<Method>() {
    579         @Override public int compare(Method a, Method b) {
    580             int comparison = Method.ORDER_BY_SIGNATURE.compare(a, b);
    581             if (comparison != 0) {
    582                 return comparison;
    583             }
    584             Class<?> aClass = a.getDeclaringClass();
    585             Class<?> bClass = b.getDeclaringClass();
    586             if (aClass == bClass) {
    587                 return 0;
    588             } else if (aClass.isAssignableFrom(bClass)) {
    589                 return 1;
    590             } else if (bClass.isAssignableFrom(aClass)) {
    591                 return -1;
    592             } else {
    593                 return 0;
    594             }
    595         }
    596     };
    597 
    598     /**
    599      * A factory function that generates, defines and returns the proxy class given
    600      * the ClassLoader and array of interfaces.
    601      */
    602     private static final class ProxyClassFactory
    603         implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    604     {
    605         // prefix for all proxy class names
    606         private static final String proxyClassNamePrefix = "$Proxy";
    607 
    608         // next number to use for generation of unique proxy class names
    609         private static final AtomicLong nextUniqueNumber = new AtomicLong();
    610 
    611         @Override
    612         public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
    613 
    614             Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
    615             for (Class<?> intf : interfaces) {
    616                 /*
    617                  * Verify that the class loader resolves the name of this
    618                  * interface to the same Class object.
    619                  */
    620                 Class<?> interfaceClass = null;
    621                 try {
    622                     interfaceClass = Class.forName(intf.getName(), false, loader);
    623                 } catch (ClassNotFoundException e) {
    624                 }
    625                 if (interfaceClass != intf) {
    626                     throw new IllegalArgumentException(
    627                         intf + " is not visible from class loader");
    628                 }
    629                 /*
    630                  * Verify that the Class object actually represents an
    631                  * interface.
    632                  */
    633                 if (!interfaceClass.isInterface()) {
    634                     throw new IllegalArgumentException(
    635                         interfaceClass.getName() + " is not an interface");
    636                 }
    637                 /*
    638                  * Verify that this interface is not a duplicate.
    639                  */
    640                 if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
    641                     throw new IllegalArgumentException(
    642                         "repeated interface: " + interfaceClass.getName());
    643                 }
    644             }
    645 
    646             String proxyPkg = null;     // package to define proxy class in
    647             int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
    648 
    649             /*
    650              * Record the package of a non-public proxy interface so that the
    651              * proxy class will be defined in the same package.  Verify that
    652              * all non-public proxy interfaces are in the same package.
    653              */
    654             for (Class<?> intf : interfaces) {
    655                 int flags = intf.getModifiers();
    656                 if (!Modifier.isPublic(flags)) {
    657                     accessFlags = Modifier.FINAL;
    658                     String name = intf.getName();
    659                     int n = name.lastIndexOf('.');
    660                     String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
    661                     if (proxyPkg == null) {
    662                         proxyPkg = pkg;
    663                     } else if (!pkg.equals(proxyPkg)) {
    664                         throw new IllegalArgumentException(
    665                             "non-public interfaces from different packages");
    666                     }
    667                 }
    668             }
    669 
    670             if (proxyPkg == null) {
    671                 // if no non-public proxy interfaces, use the default package.
    672                 proxyPkg = "";
    673             }
    674 
    675             {
    676                 // Android-changed: Generate the proxy directly instead of calling
    677                 // through to ProxyGenerator.
    678                 List<Method> methods = getMethods(interfaces);
    679                 Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
    680                 validateReturnTypes(methods);
    681                 List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
    682 
    683                 Method[] methodsArray = methods.toArray(new Method[methods.size()]);
    684                 Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
    685 
    686                 /*
    687                  * Choose a name for the proxy class to generate.
    688                  */
    689                 long num = nextUniqueNumber.getAndIncrement();
    690                 String proxyName = proxyPkg + proxyClassNamePrefix + num;
    691 
    692                 return generateProxy(proxyName, interfaces, loader, methodsArray,
    693                                      exceptionsArray);
    694             }
    695         }
    696     }
    697 
    698     /**
    699      * Remove methods that have the same name, parameters and return type. This
    700      * computes the exceptions of each method; this is the intersection of the
    701      * exceptions of equivalent methods.
    702      *
    703      * @param methods the methods to find exceptions for, ordered by name and
    704      *     signature.
    705      */
    706     private static List<Class<?>[]> deduplicateAndGetExceptions(List<Method> methods) {
    707         List<Class<?>[]> exceptions = new ArrayList<Class<?>[]>(methods.size());
    708 
    709         for (int i = 0; i < methods.size(); ) {
    710             Method method = methods.get(i);
    711             Class<?>[] exceptionTypes = method.getExceptionTypes();
    712 
    713             if (i > 0 && Method.ORDER_BY_SIGNATURE.compare(method, methods.get(i - 1)) == 0) {
    714                 exceptions.set(i - 1, intersectExceptions(exceptions.get(i - 1), exceptionTypes));
    715                 methods.remove(i);
    716             } else {
    717                 exceptions.add(exceptionTypes);
    718                 i++;
    719             }
    720         }
    721         return exceptions;
    722     }
    723 
    724     /**
    725      * Returns the exceptions that are declared in both {@code aExceptions} and
    726      * {@code bExceptions}. If an exception type in one array is a subtype of an
    727      * exception from the other, the subtype is included in the intersection.
    728      */
    729     private static Class<?>[] intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions) {
    730         if (aExceptions.length == 0 || bExceptions.length == 0) {
    731             return EmptyArray.CLASS;
    732         }
    733         if (Arrays.equals(aExceptions, bExceptions)) {
    734             return aExceptions;
    735         }
    736         Set<Class<?>> intersection = new HashSet<Class<?>>();
    737         for (Class<?> a : aExceptions) {
    738             for (Class<?> b : bExceptions) {
    739                 if (a.isAssignableFrom(b)) {
    740                     intersection.add(b);
    741                 } else if (b.isAssignableFrom(a)) {
    742                     intersection.add(a);
    743                 }
    744             }
    745         }
    746         return intersection.toArray(new Class<?>[intersection.size()]);
    747     }
    748 
    749     /**
    750      * Throws if any two methods in {@code methods} have the same name and
    751      * parameters but incompatible return types.
    752      *
    753      * @param methods the methods to find exceptions for, ordered by name and
    754      *     signature.
    755      */
    756     private static void validateReturnTypes(List<Method> methods) {
    757         Method vs = null;
    758         for (Method method : methods) {
    759             if (vs == null || !vs.equalNameAndParameters(method)) {
    760                 vs = method; // this has a different name or parameters
    761                 continue;
    762             }
    763             Class<?> returnType = method.getReturnType();
    764             Class<?> vsReturnType = vs.getReturnType();
    765             if (returnType.isInterface() && vsReturnType.isInterface()) {
    766                 // all interfaces are mutually compatible
    767             } else if (vsReturnType.isAssignableFrom(returnType)) {
    768                 vs = method; // the new return type is a subtype; use it instead
    769             } else if (!returnType.isAssignableFrom(vsReturnType)) {
    770                 throw new IllegalArgumentException("proxied interface methods have incompatible "
    771                         + "return types:\n  " + vs + "\n  " + method);
    772             }
    773         }
    774     }
    775 
    776     private static List<Method> getMethods(Class<?>[] interfaces) {
    777         List<Method> result = new ArrayList<Method>();
    778         try {
    779             result.add(Object.class.getMethod("equals", Object.class));
    780             result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
    781             result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
    782         } catch (NoSuchMethodException e) {
    783             throw new AssertionError();
    784         }
    785 
    786         getMethodsRecursive(interfaces, result);
    787         return result;
    788     }
    789 
    790     /**
    791      * Fills {@code proxiedMethods} with the methods of {@code interfaces} and
    792      * the interfaces they extend. May contain duplicates.
    793      */
    794     private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
    795         for (Class<?> i : interfaces) {
    796             getMethodsRecursive(i.getInterfaces(), methods);
    797             Collections.addAll(methods, i.getDeclaredMethods());
    798         }
    799     }
    800 
    801     @FastNative
    802     private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
    803                                                  ClassLoader loader, Method[] methods,
    804                                                  Class<?>[][] exceptions);
    805     // END Android-changed: How proxies are generated.
    806 
    807 
    808     /**
    809      * Returns an instance of a proxy class for the specified interfaces
    810      * that dispatches method invocations to the specified invocation
    811      * handler.
    812      *
    813      * <p>{@code Proxy.newProxyInstance} throws
    814      * {@code IllegalArgumentException} for the same reasons that
    815      * {@code Proxy.getProxyClass} does.
    816      *
    817      * @param   loader the class loader to define the proxy class
    818      * @param   interfaces the list of interfaces for the proxy class
    819      *          to implement
    820      * @param   h the invocation handler to dispatch method invocations to
    821      * @return  a proxy instance with the specified invocation handler of a
    822      *          proxy class that is defined by the specified class loader
    823      *          and that implements the specified interfaces
    824      * @throws  IllegalArgumentException if any of the restrictions on the
    825      *          parameters that may be passed to {@code getProxyClass}
    826      *          are violated
    827      * @throws  SecurityException if a security manager, <em>s</em>, is present
    828      *          and any of the following conditions is met:
    829      *          <ul>
    830      *          <li> the given {@code loader} is {@code null} and
    831      *               the caller's class loader is not {@code null} and the
    832      *               invocation of {@link SecurityManager#checkPermission
    833      *               s.checkPermission} with
    834      *               {@code RuntimePermission("getClassLoader")} permission
    835      *               denies access;</li>
    836      *          <li> for each proxy interface, {@code intf},
    837      *               the caller's class loader is not the same as or an
    838      *               ancestor of the class loader for {@code intf} and
    839      *               invocation of {@link SecurityManager#checkPackageAccess
    840      *               s.checkPackageAccess()} denies access to {@code intf};</li>
    841      *          <li> any of the given proxy interfaces is non-public and the
    842      *               caller class is not in the same {@linkplain Package runtime package}
    843      *               as the non-public interface and the invocation of
    844      *               {@link SecurityManager#checkPermission s.checkPermission} with
    845      *               {@code ReflectPermission("newProxyInPackage.{package name}")}
    846      *               permission denies access.</li>
    847      *          </ul>
    848      * @throws  NullPointerException if the {@code interfaces} array
    849      *          argument or any of its elements are {@code null}, or
    850      *          if the invocation handler, {@code h}, is
    851      *          {@code null}
    852      */
    853     @CallerSensitive
    854     public static Object newProxyInstance(ClassLoader loader,
    855                                           Class<?>[] interfaces,
    856                                           InvocationHandler h)
    857         throws IllegalArgumentException
    858     {
    859         Objects.requireNonNull(h);
    860 
    861         final Class<?>[] intfs = interfaces.clone();
    862         // Android-removed: SecurityManager calls
    863         /*
    864         final SecurityManager sm = System.getSecurityManager();
    865         if (sm != null) {
    866             checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    867         }
    868         */
    869 
    870         /*
    871          * Look up or generate the designated proxy class.
    872          */
    873         Class<?> cl = getProxyClass0(loader, intfs);
    874 
    875         /*
    876          * Invoke its constructor with the designated invocation handler.
    877          */
    878         try {
    879             // Android-removed: SecurityManager / permission checks.
    880             /*
    881             if (sm != null) {
    882                 checkNewProxyPermission(Reflection.getCallerClass(), cl);
    883             }
    884             */
    885 
    886             final Constructor<?> cons = cl.getConstructor(constructorParams);
    887             final InvocationHandler ih = h;
    888             if (!Modifier.isPublic(cl.getModifiers())) {
    889                 // BEGIN Android-changed: Excluded AccessController.doPrivileged call.
    890                 /*
    891                 AccessController.doPrivileged(new PrivilegedAction<Void>() {
    892                     public Void run() {
    893                         cons.setAccessible(true);
    894                         return null;
    895                     }
    896                 });
    897                 */
    898 
    899                 cons.setAccessible(true);
    900                 // END Android-removed: Excluded AccessController.doPrivileged call.
    901             }
    902             return cons.newInstance(new Object[]{h});
    903         } catch (IllegalAccessException|InstantiationException e) {
    904             throw new InternalError(e.toString(), e);
    905         } catch (InvocationTargetException e) {
    906             Throwable t = e.getCause();
    907             if (t instanceof RuntimeException) {
    908                 throw (RuntimeException) t;
    909             } else {
    910                 throw new InternalError(t.toString(), t);
    911             }
    912         } catch (NoSuchMethodException e) {
    913             throw new InternalError(e.toString(), e);
    914         }
    915     }
    916 
    917     // Android-removed: SecurityManager / permission checks.
    918     /*
    919     private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
    920         SecurityManager sm = System.getSecurityManager();
    921         if (sm != null) {
    922             if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
    923                 ClassLoader ccl = caller.getClassLoader();
    924                 ClassLoader pcl = proxyClass.getClassLoader();
    925 
    926                 // do permission check if the caller is in a different runtime package
    927                 // of the proxy class
    928                 int n = proxyClass.getName().lastIndexOf('.');
    929                 String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
    930 
    931                 n = caller.getName().lastIndexOf('.');
    932                 String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
    933 
    934                 if (pcl != ccl || !pkg.equals(callerPkg)) {
    935                     sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
    936                 }
    937             }
    938         }
    939     }
    940     */
    941 
    942     /**
    943      * Returns true if and only if the specified class was dynamically
    944      * generated to be a proxy class using the {@code getProxyClass}
    945      * method or the {@code newProxyInstance} method.
    946      *
    947      * <p>The reliability of this method is important for the ability
    948      * to use it to make security decisions, so its implementation should
    949      * not just test if the class in question extends {@code Proxy}.
    950      *
    951      * @param   cl the class to test
    952      * @return  {@code true} if the class is a proxy class and
    953      *          {@code false} otherwise
    954      * @throws  NullPointerException if {@code cl} is {@code null}
    955      */
    956     public static boolean isProxyClass(Class<?> cl) {
    957         return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
    958     }
    959 
    960     /**
    961      * Returns the invocation handler for the specified proxy instance.
    962      *
    963      * @param   proxy the proxy instance to return the invocation handler for
    964      * @return  the invocation handler for the proxy instance
    965      * @throws  IllegalArgumentException if the argument is not a
    966      *          proxy instance
    967      * @throws  SecurityException if a security manager, <em>s</em>, is present
    968      *          and the caller's class loader is not the same as or an
    969      *          ancestor of the class loader for the invocation handler
    970      *          and invocation of {@link SecurityManager#checkPackageAccess
    971      *          s.checkPackageAccess()} denies access to the invocation
    972      *          handler's class.
    973      */
    974     @CallerSensitive
    975     public static InvocationHandler getInvocationHandler(Object proxy)
    976         throws IllegalArgumentException
    977     {
    978         /*
    979          * Verify that the object is actually a proxy instance.
    980          */
    981         if (!isProxyClass(proxy.getClass())) {
    982             throw new IllegalArgumentException("not a proxy instance");
    983         }
    984 
    985         final Proxy p = (Proxy) proxy;
    986         final InvocationHandler ih = p.h;
    987         // Android-removed: SecurityManager / access checks.
    988         /*
    989         if (System.getSecurityManager() != null) {
    990             Class<?> ihClass = ih.getClass();
    991             Class<?> caller = Reflection.getCallerClass();
    992             if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
    993                                                     ihClass.getClassLoader()))
    994             {
    995                 ReflectUtil.checkPackageAccess(ihClass);
    996             }
    997         }
    998         */
    999 
   1000         return ih;
   1001     }
   1002 
   1003     // Android-added: Helper method invoke(Proxy, Method, Object[]) for ART native code.
   1004     private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
   1005         InvocationHandler h = proxy.h;
   1006         return h.invoke(proxy, method, args);
   1007     }
   1008 }
   1009