15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2008 The Android Open Source Project
35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License");
55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License.
65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at
75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *      http://www.apache.org/licenses/LICENSE-2.0
95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software
115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS,
125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and
145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License.
155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.io.File;
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.io.IOException;
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Constructor;
20f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstromimport java.lang.reflect.Method;
21f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstromimport java.util.Enumeration;
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * DexFile tests (Dalvik-specific).
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main {
276ce558b97f80d4ef7be2ef43333101d1aac7dcbfTDYa    private static final String CLASS_PATH = System.getenv("DEX_LOCATION") + "/071-dexfile-ex.jar";
286ce558b97f80d4ef7be2ef43333101d1aac7dcbfTDYa    private static final String ODEX_DIR = System.getenv("DEX_LOCATION");
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static final String ODEX_ALT = "/tmp";
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static final String LIB_DIR = "/nowhere/nothing/";
315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
32f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    private static final String getOdexDir() {
33f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        return new File(ODEX_DIR).isDirectory() ? ODEX_DIR : ODEX_ALT;
34f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    }
35f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom
365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Prep the environment then run the test.
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
39f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    public static void main(String[] args) throws Exception {
40f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        /*
41f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         * Create a sub-process to see if the ProcessManager wait
42f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         * interferes with the dexopt invocation wait.
43f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         *
44f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         * /dev/random never hits EOF, so we're sure that we'll still
45f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         * be waiting for the process to complete.  On the device it
46f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         * stops pretty quickly (which means the child won't be
47f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         * spinning).
48f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom         */
49f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random");
50f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Process p = pb.start();
51f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom
52f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        testDexClassLoader();
53f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        testDexFile();
54f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom
55f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        // shouldn't be necessary, but it's good to be tidy
56f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        p.destroy();
57f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        // let the ProcessManager's daemon thread finish before we shut down
58f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        // (avoids the occasional segmentation fault)
59f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Thread.sleep(500);
605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("done");
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Create a class loader, explicitly specifying the source DEX and
655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * the location for the optimized DEX.
665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
67f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    private static void testDexClassLoader() throws Exception {
685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        ClassLoader dexClassLoader = getDexClassLoader();
69f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Class Another = dexClassLoader.loadClass("Another");
70f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Object another = Another.newInstance();
715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // not expected to work; just exercises the call
725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        dexClassLoader.getResource("nonexistent");
735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /*
765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Create an instance of DexClassLoader.  The test harness doesn't
775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * have visibility into dalvik.system.*, so we do this through
785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * reflection.
795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
80f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    private static ClassLoader getDexClassLoader() throws Exception {
81f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        ClassLoader classLoader = Main.class.getClassLoader();
82f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Class DexClassLoader = classLoader.loadClass("dalvik.system.DexClassLoader");
83f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Constructor DexClassLoader_init = DexClassLoader.getConstructor(String.class,
84f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom                                                                        String.class,
85f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom                                                                        String.class,
86f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom                                                                        ClassLoader.class);
875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // create an instance, using the path we found
88f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        return (ClassLoader) DexClassLoader_init.newInstance(CLASS_PATH, getOdexDir(), LIB_DIR, classLoader);
89f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    }
905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
91f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom    private static void testDexFile() throws Exception {
92f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        ClassLoader classLoader = Main.class.getClassLoader();
93f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Class DexFile = classLoader.loadClass("dalvik.system.DexFile");
94f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Method DexFile_loadDex = DexFile.getMethod("loadDex",
95f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom                                                   String.class,
96f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom                                                   String.class,
97f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom                                                   Integer.TYPE);
98f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Method DexFile_entries = DexFile.getMethod("entries");
99f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Object dexFile = DexFile_loadDex.invoke(null, CLASS_PATH, null, 0);
100f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        Enumeration<String> e = (Enumeration<String>) DexFile_entries.invoke(dexFile);
101f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        while (e.hasMoreElements()) {
102f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom            String className = e.nextElement();
103f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom            System.out.println(className);
104f2f9daf9ba33b15abddfc8f8d03a708a7908b765Brian Carlstrom        }
1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
107