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      */
Proxy()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      */
Proxy(InvocationHandler h)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
getProxyClass(ClassLoader loader, Class<?>... interfaces)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      */
getProxyClass0(ClassLoader loader, Class<?>... interfaces)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 
Key1(Class<?> intf)457         Key1(Class<?> intf) {
458             super(intf);
459             this.hash = intf.hashCode();
460         }
461 
462         @Override
hashCode()463         public int hashCode() {
464             return hash;
465         }
466 
467         @Override
equals(Object obj)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 
Key2(Class<?> intf1, Class<?> intf2)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
hashCode()492         public int hashCode() {
493             return hash;
494         }
495 
496         @Override
equals(Object obj)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")
KeyX(Class<?>[] interfaces)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
hashCode()527         public int hashCode() {
528             return hash;
529         }
530 
531         @Override
equals(Object obj)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 
equals(WeakReference<Class<?>>[] refs1, WeakReference<Class<?>>[] refs2)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
apply(ClassLoader classLoader, Class<?>[] interfaces)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
apply(ClassLoader loader, Class<?>[] interfaces)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      */
deduplicateAndGetExceptions(List<Method> methods)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      */
intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions)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      */
validateReturnTypes(List<Method> methods)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 
getMethods(Class<?>[] interfaces)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      */
getMethodsRecursive(Class<?>[] interfaces, List<Method> methods)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
generateProxy(String name, Class<?>[] interfaces, ClassLoader loader, Method[] methods, Class<?>[][] exceptions)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
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)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-removed: 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      */
isProxyClass(Class<?> cl)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
getInvocationHandler(Object proxy)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.
invoke(Proxy proxy, Method method, Object[] args)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