Home | History | Annotate | Download | only in src
      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 
     21 /**
     22  * DexFile tests (Dalvik-specific).
     23  */
     24 public class Main {
     25     private static final String CLASS_PATH = System.getenv("DEX_LOCATION") + "/071-dexfile-ex.jar";
     26     private static final String ODEX_DIR = System.getenv("DEX_LOCATION");
     27     //private static final String ODEX_DIR = ".";
     28     private static final String ODEX_ALT = "/tmp";
     29     private static final String LIB_DIR = "/nowhere/nothing/";
     30 
     31     /**
     32      * Prep the environment then run the test.
     33      */
     34     public static void main(String[] args) {
     35         Process p;
     36         try {
     37             /*
     38              * Create a sub-process to see if the ProcessManager wait
     39              * interferes with the dexopt invocation wait.
     40              *
     41              * /dev/random never hits EOF, so we're sure that we'll still
     42              * be waiting for the process to complete.  On the device it
     43              * stops pretty quickly (which means the child won't be
     44              * spinning).
     45              */
     46             ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random");
     47             p = pb.start();
     48         } catch (IOException ioe) {
     49             System.err.println("cmd failed: " + ioe.getMessage());
     50             p = null;
     51         }
     52 
     53         try {
     54             testDexClassLoader();
     55         } finally {
     56             // shouldn't be necessary, but it's good to be tidy
     57             if (p != null) {
     58                 p.destroy();
     59             }
     60 
     61             // let the ProcessManager's daemon thread finish before we shut down
     62             // (avoids the occasional segmentation fault)
     63             try {
     64                 Thread.sleep(500);
     65             } catch (Exception ex) {}
     66         }
     67 
     68         System.out.println("done");
     69     }
     70 
     71     /**
     72      * Create a class loader, explicitly specifying the source DEX and
     73      * the location for the optimized DEX.
     74      */
     75     private static void testDexClassLoader() {
     76         ClassLoader dexClassLoader = getDexClassLoader();
     77 
     78         Class anotherClass;
     79         try {
     80             anotherClass = dexClassLoader.loadClass("Another");
     81         } catch (ClassNotFoundException cnfe) {
     82             throw new RuntimeException("Another?", cnfe);
     83         }
     84 
     85         Object another;
     86         try {
     87             another = anotherClass.newInstance();
     88         } catch (IllegalAccessException ie) {
     89             throw new RuntimeException("new another", ie);
     90         } catch (InstantiationException ie) {
     91             throw new RuntimeException("new another", ie);
     92         }
     93 
     94         // not expected to work; just exercises the call
     95         dexClassLoader.getResource("nonexistent");
     96     }
     97 
     98     /*
     99      * Create an instance of DexClassLoader.  The test harness doesn't
    100      * have visibility into dalvik.system.*, so we do this through
    101      * reflection.
    102      */
    103     private static ClassLoader getDexClassLoader() {
    104         String odexDir;
    105 
    106         if (false) {
    107             String androidData = System.getenv("ANDROID_DATA");
    108             if (androidData == null) {
    109                 androidData = "";
    110             }
    111             odexDir = androidData + "/" + ODEX_DIR;
    112         }
    113 
    114         File test = new File(ODEX_DIR);
    115         if (test.isDirectory()) {
    116             odexDir = ODEX_DIR;
    117         } else {
    118             odexDir = ODEX_ALT;
    119         }
    120         if (false) {
    121             System.out.println("Output dir is " + odexDir);
    122         }
    123 
    124         ClassLoader myLoader = Main.class.getClassLoader();
    125         Class dclClass;
    126         try {
    127             dclClass = myLoader.loadClass("dalvik.system.DexClassLoader");
    128         } catch (ClassNotFoundException cnfe) {
    129             throw new RuntimeException("dalvik.system.DexClassLoader not found", cnfe);
    130         }
    131 
    132         Constructor ctor;
    133         try {
    134             ctor = dclClass.getConstructor(String.class, String.class,
    135                 String.class, ClassLoader.class);
    136         } catch (NoSuchMethodException nsme) {
    137             throw new RuntimeException("DCL ctor", nsme);
    138         }
    139 
    140         // create an instance, using the path we found
    141         Object dclObj;
    142         try {
    143             dclObj = ctor.newInstance(CLASS_PATH, odexDir, LIB_DIR, myLoader);
    144         } catch (Exception ex) {
    145             throw new RuntimeException("DCL newInstance", ex);
    146         }
    147 
    148         return (ClassLoader) dclObj;
    149     }
    150 }
    151