Merge "Add tests for ALPN-related methods."
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index 9839889..d346bb8 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -83,34 +83,30 @@
 
     /**
      * Reports the current class loader chain to the registered {@code reporter}.
-     * The chain is reported only if all its elements are {@code BaseDexClassLoader}.
      */
     private void reportClassLoaderChain() {
-        ArrayList<BaseDexClassLoader> classLoadersChain = new ArrayList<>();
+        ArrayList<ClassLoader> classLoadersChain = new ArrayList<>();
         ArrayList<String> classPaths = new ArrayList<>();
 
         classLoadersChain.add(this);
         classPaths.add(String.join(File.pathSeparator, pathList.getDexPaths()));
 
-        boolean onlySawSupportedClassLoaders = true;
         ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
         ClassLoader current = getParent();
 
         while (current != null && current != bootClassLoader) {
+            classLoadersChain.add(current);
             if (current instanceof BaseDexClassLoader) {
                 BaseDexClassLoader bdcCurrent = (BaseDexClassLoader) current;
-                classLoadersChain.add(bdcCurrent);
                 classPaths.add(String.join(File.pathSeparator, bdcCurrent.pathList.getDexPaths()));
             } else {
-                onlySawSupportedClassLoaders = false;
-                break;
+                // We can't determine the classpath for arbitrary class loaders.
+                classPaths.add(null);
             }
             current = current.getParent();
         }
 
-        if (onlySawSupportedClassLoaders) {
-            reporter.report(classLoadersChain, classPaths);
-        }
+        reporter.report(classLoadersChain, classPaths);
     }
 
     /**
@@ -277,7 +273,6 @@
         /**
          * Reports the construction of a BaseDexClassLoader and provides information about the
          * class loader chain.
-         * Note that this only reports if all class loader in the chain are BaseDexClassLoader.
          *
          * @param classLoadersChain the chain of class loaders used during the construction of the
          *     class loader. The first element is the BaseDexClassLoader being constructed,
@@ -285,9 +280,10 @@
          * @param classPaths the class paths of the class loaders present in
          *     {@param classLoadersChain}. The first element corresponds to the first class
          *     loader and so on. A classpath is represented as a list of dex files separated by
-         *     {@code File.pathSeparator}.
+         *     {@code File.pathSeparator}. If the class loader is not a BaseDexClassLoader the
+         *     classpath will be null.
          */
         @libcore.api.CorePlatformApi
-        void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths);
+        void report(List<ClassLoader> classLoadersChain, List<String> classPaths);
     }
 }
diff --git a/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java
index e7421b7..4bc322e 100644
--- a/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java
@@ -16,6 +16,11 @@
 
 package libcore.dalvik.system;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 import dalvik.system.BaseDexClassLoader;
 import dalvik.system.PathClassLoader;
 import java.io.File;
@@ -26,62 +31,115 @@
 
 import libcore.io.Streams;
 
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
-public final class BaseDexClassLoaderTest extends TestCase {
+@RunWith(JUnit4.class)
+public final class BaseDexClassLoaderTest {
     private static class Reporter implements BaseDexClassLoader.Reporter {
-        public List<BaseDexClassLoader> classLoaders = new ArrayList<>();
-        public List<String> loadedDexPaths = new ArrayList<>();
+        public final List<ClassLoader> classLoaders = new ArrayList<>();
+        public final List<String> loadedDexPaths = new ArrayList<>();
 
         @Override
-        public void report(List<BaseDexClassLoader> loaders, List<String> dexPaths) {
+        public void report(List<ClassLoader> loaders, List<String> dexPaths) {
             classLoaders.addAll(loaders);
             loadedDexPaths.addAll(dexPaths);
         }
+
+        void reset() {
+            classLoaders.clear();
+            loadedDexPaths.clear();
+        }
     }
 
-    public void testReporting() throws Exception {
+    private ClassLoader pcl;
+    private File jar;
+    private Reporter reporter;
+
+    @Before
+    public void extractTestJar() throws Exception {
         // Extract loading-test.jar from the resource.
-        ClassLoader pcl = BaseDexClassLoaderTest.class.getClassLoader();
-        File jar = File.createTempFile("loading-test", ".jar");
+        pcl = BaseDexClassLoaderTest.class.getClassLoader();
+        jar = File.createTempFile("loading-test", ".jar");
         try (InputStream in = pcl.getResourceAsStream("dalvik/system/loading-test.jar");
              FileOutputStream out = new FileOutputStream(jar)) {
           Streams.copy(in, out);
         }
+    }
 
-        // Set the reporter.
-        Reporter reporter = new Reporter();
+    @Before
+    public void registerReporter() {
+        reporter = new Reporter();
         BaseDexClassLoader.setReporter(reporter);
+    }
+
+    @After
+    public void unregisterReporter() {
+        BaseDexClassLoader.setReporter(null);
+    }
+
+    @After
+    public void deleteTestJar() throws Exception {
+        assertTrue(jar.delete());
+    }
+
+    @Test
+    public void testReporting() throws Exception {
         // Load the jar file using a PathClassLoader.
         BaseDexClassLoader cl1 = new PathClassLoader(jar.getPath(),
             ClassLoader.getSystemClassLoader());
 
-        // Verify the reporter files.
+        // Verify the reported data.
         assertEquals(2, reporter.loadedDexPaths.size());
         assertEquals(2, reporter.classLoaders.size());
 
         // First class loader should be the one loading the files
         assertEquals(jar.getPath(), reporter.loadedDexPaths.get(0));
         assertEquals(cl1, reporter.classLoaders.get(0));
+
         // Second class loader should be the system class loader.
         // Don't check the actual classpath as that might vary based on system properties.
         assertEquals(ClassLoader.getSystemClassLoader(), reporter.classLoaders.get(1));
+    }
 
-        // Reset the reporter and check we don't report anymore.
-        BaseDexClassLoader.setReporter(null);
+    @Test
+    public void testReportingUnknownLoader() throws Exception {
+        // Add an unknown classloader between cl1 and the system
+        ClassLoader unknownLoader = new ClassLoader(ClassLoader.getSystemClassLoader()) {};
+        BaseDexClassLoader cl1 = new PathClassLoader(jar.getPath(), unknownLoader);
+
+        assertEquals(3, reporter.loadedDexPaths.size());
+        assertEquals(3, reporter.classLoaders.size());
+
+        assertEquals(jar.getPath(), reporter.loadedDexPaths.get(0));
+        assertEquals(cl1, reporter.classLoaders.get(0));
+
+        assertNull(reporter.loadedDexPaths.get(1));
+        assertEquals(unknownLoader, reporter.classLoaders.get(1));
+
+        assertEquals(ClassLoader.getSystemClassLoader(), reporter.classLoaders.get(2));
+    }
+
+    @Test
+    public void testNoReportingAfterResetting() throws Exception {
+        BaseDexClassLoader cl1 = new PathClassLoader(jar.getPath(),
+            ClassLoader.getSystemClassLoader());
+
+        assertEquals(2, reporter.loadedDexPaths.size());
+        assertEquals(2, reporter.classLoaders.size());
+
+        // Check we don't report after the reporter is unregistered.
+        unregisterReporter();
+        reporter.reset();
 
         // Load the jar file using another PathClassLoader.
         BaseDexClassLoader cl2 = new PathClassLoader(jar.getPath(), pcl);
 
-        // Verify the list reporter files did not change.
-        assertEquals(2, reporter.loadedDexPaths.size());
-        assertEquals(2, reporter.classLoaders.size());
-
-        assertEquals(jar.getPath(), reporter.loadedDexPaths.get(0));
-        assertEquals(cl1, reporter.classLoaders.get(0));
-        assertEquals(ClassLoader.getSystemClassLoader(), reporter.classLoaders.get(1));
-
-        // Clean up the extracted jar file.
-        assertTrue(jar.delete());
+        // Verify nothing reported
+        assertEquals(0, reporter.loadedDexPaths.size());
+        assertEquals(0, reporter.classLoaders.size());
     }
 }