Merge "Inject anonymous inner classes of injected classes" into mnc-dev
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index 3aa7cdf..f6c2626 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -24,9 +24,11 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -86,7 +88,23 @@
     public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
         mLog = log;
         mOsDestJar = osDestJar;
-        mInjectClasses = createInfo.getInjectedClasses();
+        ArrayList<Class<?>> injectedClasses =
+                new ArrayList<Class<?>>(Arrays.asList(createInfo.getInjectedClasses()));
+        // Search for and add anonymous inner classes also.
+        ListIterator<Class<?>> iter = injectedClasses.listIterator();
+        while (iter.hasNext()) {
+            Class<?> clazz = iter.next();
+            try {
+                int i = 1;
+                while(i < 100) {
+                    iter.add(Class.forName(clazz.getName() + "$" + i));
+                    i++;
+                }
+            } catch (ClassNotFoundException ignored) {
+                // Expected.
+            }
+        }
+        mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
         mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods()));
 
         // Create the map/set of methods to change to delegates
@@ -290,13 +308,7 @@
      * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
      */
     private String classToEntryPath(Class<?> clazz) {
-        String name = "";
-        Class<?> parent;
-        while ((parent = clazz.getEnclosingClass()) != null) {
-            name = "$" + clazz.getSimpleName() + name;
-            clazz = parent;
-        }
-        return classNameToEntryPath(clazz.getCanonicalName() + name);
+        return classNameToEntryPath(clazz.getName());
     }
 
     /**
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index deb94c4..27ab5ea 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -136,6 +136,8 @@
             ICreateInfo.class,
             CreateInfo.class,
             LayoutlibDelegate.class,
+            InjectMethodRunnable.class,
+            InjectMethodRunnables.class,
             /* Java package classes */
             AutoCloseable.class,
             Objects.class,
@@ -302,4 +304,3 @@
                         InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
             }};
 }
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
index ac10639..54b1fe6 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
@@ -85,6 +85,12 @@
     Map<String, InjectMethodRunnable> getInjectedMethodsMap();
 
     abstract class InjectMethodRunnable {
-        public abstract void generateMethods(ClassVisitor cv);
+        /**
+         * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
+         * loading the class, ClassVisitor is not loaded. This is because when injecting
+         * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
+         * asm classes also, but still keep CreateInfo loadable.
+         */
+        public abstract void generateMethods(Object cv);
     }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
index 39d46d7..37fc096 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
@@ -30,7 +30,9 @@
     public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER
             = new InjectMethodRunnable() {
         @Override
-        public void generateMethods(ClassVisitor cv) {
+        public void generateMethods(Object classVisitor) {
+            assert classVisitor instanceof ClassVisitor;
+            ClassVisitor cv = (ClassVisitor) classVisitor;
             // generated by compiling the class:
             // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } }
             // and then running ASMifier on it: