1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.io.File;
18 import java.io.IOException;
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.Method;
21 import java.util.Enumeration;
22 
23 /**
24  * DexFile tests (Dalvik-specific).
25  */
26 public class Main {
27     private static final String CLASS_PATH = System.getenv("DEX_LOCATION") + "/071-dexfile-ex.jar";
28     private static final String ODEX_DIR = System.getenv("DEX_LOCATION");
29     private static final String ODEX_ALT = "/tmp";
30     private static final String LIB_DIR = "/nowhere/nothing/";
31 
getOdexDir()32     private static final String getOdexDir() {
33         return new File(ODEX_DIR).isDirectory() ? ODEX_DIR : ODEX_ALT;
34     }
35 
36     /**
37      * Prep the environment then run the test.
38      */
main(String[] args)39     public static void main(String[] args) throws Exception {
40         /*
41          * Create a sub-process to see if the ProcessManager wait
42          * interferes with the dexopt invocation wait.
43          *
44          * /dev/random never hits EOF, so we're sure that we'll still
45          * be waiting for the process to complete.  On the device it
46          * stops pretty quickly (which means the child won't be
47          * spinning).
48          */
49         ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random");
50         Process p = pb.start();
51 
52         testDexClassLoader();
53         testDexFile();
54 
55         // shouldn't be necessary, but it's good to be tidy
56         p.destroy();
57         // let the ProcessManager's daemon thread finish before we shut down
58         // (avoids the occasional segmentation fault)
59         Thread.sleep(500);
60         System.out.println("done");
61     }
62 
63     /**
64      * Create a class loader, explicitly specifying the source DEX and
65      * the location for the optimized DEX.
66      */
testDexClassLoader()67     private static void testDexClassLoader() throws Exception {
68         ClassLoader dexClassLoader = getDexClassLoader();
69         Class Another = dexClassLoader.loadClass("Another");
70         Object another = Another.newInstance();
71         // not expected to work; just exercises the call
72         dexClassLoader.getResource("nonexistent");
73     }
74 
75     /*
76      * Create an instance of DexClassLoader.  The test harness doesn't
77      * have visibility into dalvik.system.*, so we do this through
78      * reflection.
79      */
getDexClassLoader()80     private static ClassLoader getDexClassLoader() throws Exception {
81         ClassLoader classLoader = Main.class.getClassLoader();
82         Class DexClassLoader = classLoader.loadClass("dalvik.system.DexClassLoader");
83         Constructor DexClassLoader_init = DexClassLoader.getConstructor(String.class,
84                                                                         String.class,
85                                                                         String.class,
86                                                                         ClassLoader.class);
87         // create an instance, using the path we found
88         return (ClassLoader) DexClassLoader_init.newInstance(CLASS_PATH, getOdexDir(), LIB_DIR, classLoader);
89     }
90 
testDexFile()91     private static void testDexFile() throws Exception {
92         ClassLoader classLoader = Main.class.getClassLoader();
93         Class DexFile = classLoader.loadClass("dalvik.system.DexFile");
94         Method DexFile_loadDex = DexFile.getMethod("loadDex",
95                                                    String.class,
96                                                    String.class,
97                                                    Integer.TYPE);
98         Method DexFile_entries = DexFile.getMethod("entries");
99         Object dexFile = DexFile_loadDex.invoke(null, CLASS_PATH, null, 0);
100         Enumeration<String> e = (Enumeration<String>) DexFile_entries.invoke(dexFile);
101         while (e.hasMoreElements()) {
102             String className = e.nextElement();
103             System.out.println(className);
104         }
105     }
106 }
107