aboutsummaryrefslogtreecommitdiff
path: root/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java')
-rw-r--r--dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java68
1 files changed, 42 insertions, 26 deletions
diff --git a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
index b618c84..1363894 100644
--- a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
+++ b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
@@ -140,6 +140,8 @@ public final class ProxyBuilder<T> {
private Class<?>[] constructorArgTypes = new Class[0];
private Object[] constructorArgValues = new Object[0];
private Set<Class<?>> interfaces = new HashSet<>();
+ private Method[] methods;
+ private boolean sharedClassLoader;
private ProxyBuilder(Class<T> clazz) {
baseClass = clazz;
@@ -195,6 +197,16 @@ public final class ProxyBuilder<T> {
return this;
}
+ public ProxyBuilder<T> onlyMethods(Method[] methods) {
+ this.methods = methods;
+ return this;
+ }
+
+ public ProxyBuilder<T> withSharedClassLoader() {
+ this.sharedClassLoader = true;
+ return this;
+ }
+
/**
* Create a new instance of the class to proxy.
*
@@ -249,12 +261,10 @@ public final class ProxyBuilder<T> {
@SuppressWarnings("unchecked")
Class<? extends T> proxyClass = (Class) generatedProxyClasses.get(baseClass);
if (proxyClass != null) {
- boolean shareClassLoader = Boolean.parseBoolean(System.getProperty(
- "dexmaker.share_classloader", "false"));
boolean validClassLoader;
- if (shareClassLoader) {
- ClassLoader parent = parentClassLoader != null ? parentClassLoader
- : baseClass.getClassLoader();
+ if (sharedClassLoader) {
+ ClassLoader parent = parentClassLoader != null ? parentClassLoader : baseClass
+ .getClassLoader();
validClassLoader = proxyClass.getClassLoader() == parent;
} else {
validClassLoader = proxyClass.getClassLoader().getParent() == parentClassLoader;
@@ -270,11 +280,28 @@ public final class ProxyBuilder<T> {
TypeId<? extends T> generatedType = TypeId.get("L" + generatedName + ";");
TypeId<T> superType = TypeId.get(baseClass);
generateConstructorsAndFields(dexMaker, generatedType, superType, baseClass);
- Method[] methodsToProxy = getMethodsToProxyRecursive();
+
+ Method[] methodsToProxy;
+ if (methods == null) {
+ methodsToProxy = getMethodsToProxyRecursive();
+ } else {
+ methodsToProxy = methods;
+ }
+
+ // Sort the results array so that they are in a deterministic fashion.
+ Arrays.sort(methodsToProxy, new Comparator<Method>() {
+ @Override
+ public int compare(Method method1, Method method2) {
+ return method1.toString().compareTo(method2.toString());
+ }
+ });
+
generateCodeForAllMethods(dexMaker, generatedType, methodsToProxy, superType);
dexMaker.declare(generatedType, generatedName + ".generated", PUBLIC, superType, getInterfacesAsTypeIds());
- ClassLoader classLoader = dexMaker.generateAndLoad(baseClass.getClassLoader(),
- parentClassLoader, dexCache);
+ if (sharedClassLoader) {
+ dexMaker.setSharedClassLoader(baseClass.getClassLoader());
+ }
+ ClassLoader classLoader = dexMaker.generateAndLoad(parentClassLoader, dexCache);
try {
proxyClass = loadClass(classLoader, generatedName);
} catch (IllegalAccessError e) {
@@ -654,22 +681,11 @@ public final class ProxyBuilder<T> {
results[i++] = entry.originalMethod;
}
- // Sort the results array so that they are returned by this method
- // in a deterministic fashion.
- Arrays.sort(results, new Comparator<Method>() {
- @Override
- public int compare(Method method1, Method method2) {
- return method1.toString().compareTo(method2.toString());
- }
- });
-
return results;
}
private void getMethodsToProxy(Set<MethodSetEntry> sink, Set<MethodSetEntry> seenFinalMethods,
Class<?> c) {
- boolean shareClassLoader = Boolean.parseBoolean(System.getProperty(
- "dexmaker.share_classloader", "false"));
for (Method method : c.getDeclaredMethods()) {
if ((method.getModifiers() & Modifier.FINAL) != 0) {
// Skip final methods, we can't override them. We
@@ -687,8 +703,8 @@ public final class ProxyBuilder<T> {
continue;
}
if (!Modifier.isPublic(method.getModifiers())
- && !Modifier.isProtected(method.getModifiers())
- && (!shareClassLoader || Modifier.isPrivate(method.getModifiers()))) {
+ && !Modifier.isProtected(method.getModifiers())
+ && (!sharedClassLoader || Modifier.isPrivate(method.getModifiers()))) {
// Skip private methods, since they are invoked through direct
// invocation (as opposed to virtual). Therefore, it would not
// be possible to intercept any private method defined inside
@@ -820,11 +836,11 @@ public final class ProxyBuilder<T> {
* another. For these purposes, we consider two methods to be equal if they have the same
* name, return type, and parameter types.
*/
- private static class MethodSetEntry {
- private final String name;
- private final Class<?>[] paramTypes;
- private final Class<?> returnType;
- private final Method originalMethod;
+ public static class MethodSetEntry {
+ public final String name;
+ public final Class<?>[] paramTypes;
+ public final Class<?> returnType;
+ public final Method originalMethod;
public MethodSetEntry(Method method) {
originalMethod = method;