1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage dalvik.system; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.File; 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileNotFoundException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 235c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilsonimport libcore.io.ErrnoException; 245c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilsonimport libcore.io.Libcore; 255c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilsonimport libcore.io.StructStat; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Manipulates DEX files. The class is similar in principle to 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link java.util.zip.ZipFile}. It is used primarily by class loaders. 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note we don't directly open and read the DEX file here. They're memory-mapped 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read-only by the VM. 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class DexFile { 35a2dc5f83493ea8f514ff8a8df4c85dcce6093d9fAndy McFadden private int mCookie; 36f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom private final String mFileName; 3712f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom private final CloseGuard guard = CloseGuard.get(); 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Opens a DEX file from a given File object. This will usually be a ZIP/JAR 410fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * file with a "classes.dex" inside. 420fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * 43d1c610c2a641157df80aa8aefefc49393074f507Elliott Hughes * The VM will generate the name of the corresponding file in 440fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * /data/dalvik-cache and open it, possibly creating or updating 450fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * it first if system permissions allow. Don't pass in the name of 460fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * a file in /data/dalvik-cache, as the named file is expected to be 470fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * in its original (pre-dexopt) state. 48f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param file 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the File object referencing the actual DEX file 51f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs, such as the file not being found or 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access rights missing for opening it 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DexFile(File file) throws IOException { 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(file.getPath()); 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Opens a DEX file from a given filename. This will usually be a ZIP/JAR 620fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * file with a "classes.dex" inside. 630fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * 64d1c610c2a641157df80aa8aefefc49393074f507Elliott Hughes * The VM will generate the name of the corresponding file in 650fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * /data/dalvik-cache and open it, possibly creating or updating 660fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * it first if system permissions allow. Don't pass in the name of 670fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * a file in /data/dalvik-cache, as the named file is expected to be 680fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * in its original (pre-dexopt) state. 69f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param fileName 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the filename of the DEX file 72f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs, such as the file not being found or 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access rights missing for opening it 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DexFile(String fileName) throws IOException { 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mCookie = openDexFile(fileName, null, 0); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mFileName = fileName; 8012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom guard.open("close"); 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //System.out.println("DEX FILE cookie is " + mCookie); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Opens a DEX file from a given filename, using a specified file 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to hold the optimized data. 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sourceName 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Jar or APK file with "classes.dex". 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputName 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * File that will hold the optimized form of the DEX data. 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param flags 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enable optional features. 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9524923f9042b142165f7176f1aa44a797145f11a7Elliott Hughes private DexFile(String sourceName, String outputName, int flags) throws IOException { 965c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson if (outputName != null) { 975c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson try { 985c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson String parent = new File(outputName).getParent(); 995c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson if (Libcore.os.getuid() != Libcore.os.stat(parent).st_uid) { 1005c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson throw new IllegalArgumentException("Optimized data directory " + parent 1015c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson + " is not owned by the current user. Shared storage cannot protect" 1025c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson + " your application from code injection attacks."); 1035c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } 1045c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } catch (ErrnoException ignored) { 1055c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson // assume we'll fail with a more contextual error later 1065c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } 1075c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } 1085c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mCookie = openDexFile(sourceName, outputName, flags); 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mFileName = sourceName; 11112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom guard.open("close"); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //System.out.println("DEX FILE cookie is " + mCookie); 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Open a DEX file, specifying the file in which the optimized DEX 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * data should be written. If the optimized form exists and appears 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to be current, it will be used; if not, the VM will attempt to 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * regenerate it. 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is intended for use by applications that wish to download 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and execute DEX files outside the usual application installation 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mechanism. This function should not be called directly by an 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * application; instead, use a class loader such as 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dalvik.system.DexClassLoader. 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sourcePathName 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Jar or APK file with "classes.dex". (May expand this to include 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "raw DEX" in the future.) 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputPathName 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * File that will hold the optimized form of the DEX data. 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param flags 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enable optional features. (Currently none defined.) 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A new or previously-opened DexFile. 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If unable to open the source or output file. 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static public DexFile loadDex(String sourcePathName, String outputPathName, 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int flags) throws IOException { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TODO: we may want to cache previously-opened DexFile objects. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cache would be synchronized with close(). This would help 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * us avoid mapping the same DEX more than once when an app 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decided to open it multiple times. In practice this may not 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be a real issue. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new DexFile(sourcePathName, outputPathName, flags); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the name of the (already opened) DEX file. 154f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the file name 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return mFileName; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the DEX file. 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 164be9c142fd80574e5d15571dad2562cd6894e2c81Andy McFadden * This may not be able to release any resources. If classes from this 165be9c142fd80574e5d15571dad2562cd6894e2c81Andy McFadden * DEX file are still resident, the DEX file can't be unmapped. 166f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs during closing the file, which 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * normally should not happen 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 172f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom guard.close(); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project closeDexFile(mCookie); 174a2dc5f83493ea8f514ff8a8df4c85dcce6093d9fAndy McFadden mCookie = 0; 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Loads a class. Returns the class on success, or a {@code null} reference 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on failure. 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If you are not calling this from a class loader, this is most likely not 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * going to do what you want. Use {@link Class#forName(String)} instead. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The method does not throw {@link ClassNotFoundException} if the class 185be9c142fd80574e5d15571dad2562cd6894e2c81Andy McFadden * isn't found because it isn't reasonable to throw exceptions wildly every 186be9c142fd80574e5d15571dad2562cd6894e2c81Andy McFadden * time a class is not found in the first DEX file we look at. 187f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class name, which should look like "java/lang/String" 190f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loader 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class loader that tries to load the class (in most cases 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the caller of the method 194f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@link Class} object representing the class, or {@code null} 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class cannot be loaded 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Class loadClass(String name, ClassLoader loader) { 1990fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden String slashName = name.replace('.', '/'); 2000fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden return loadClassBinaryName(slashName, loader); 2010fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden } 2020fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden 2030fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden /** 2040fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * See {@link #loadClass(String, ClassLoader)}. 2050fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * 2060fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * This takes a "binary" class name to better match ClassLoader semantics. 2070fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * 208fb374e129dc73d4adafc9441ca78011676a26d9fCarl Shapiro * @hide 2090fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden */ 2100fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden public Class loadClassBinaryName(String name, ClassLoader loader) { 2118647680e6a884b504a9f502e0f6a24218fdf675cElliott Hughes return defineClass(name, loader, mCookie); 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2130fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden 2148647680e6a884b504a9f502e0f6a24218fdf675cElliott Hughes private native static Class defineClass(String name, ClassLoader loader, int cookie); 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enumerate the names of the classes in this DEX file. 218f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an enumeration of names of classes contained in the DEX file, in 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the usual internal form (like "java/lang/String"). 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Enumeration<String> entries() { 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new DFEnum(this); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Helper class. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class DFEnum implements Enumeration<String> { 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int mIndex; 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String[] mNameList; 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DFEnum(DexFile df) { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mIndex = 0; 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mNameList = getClassNameList(mCookie); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasMoreElements() { 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (mIndex < mNameList.length); 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String nextElement() { 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return mNameList[mIndex++]; 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* return a String array with class names */ 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project native private static String[] getClassNameList(int cookie); 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 250f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes /** 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Called when the class is finalized. Makes sure the DEX file is closed. 252f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs during closing the file, which 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * normally should not happen 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 257e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 258e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 25912f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom if (guard != null) { 26012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom guard.warnIfOpen(); 26112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom } 262e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom close(); 263e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 264e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 265e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Open a DEX file. The value returned is a magic VM cookie. On 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure, an IOException is thrown. 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project native private static int openDexFile(String sourceName, String outputName, 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int flags) throws IOException; 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 2768abd4e471456bc479401d652de61de7c9ba85661Dan Bornstein * Open a DEX file based on a {@code byte[]}. The value returned 2778abd4e471456bc479401d652de61de7c9ba85661Dan Bornstein * is a magic VM cookie. On failure, a RuntimeException is thrown. 2788abd4e471456bc479401d652de61de7c9ba85661Dan Bornstein */ 2798abd4e471456bc479401d652de61de7c9ba85661Dan Bornstein native private static int openDexFile(byte[] fileContents); 2808abd4e471456bc479401d652de61de7c9ba85661Dan Bornstein 2818abd4e471456bc479401d652de61de7c9ba85661Dan Bornstein /* 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Close DEX file. 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project native private static void closeDexFile(int cookie); 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the VM believes that the apk/jar file is out of date 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and should be passed through "dexopt" again. 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param fileName the absolute path to the apk/jar file to examine. 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if dexopt should be called on the file, false otherwise. 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.io.FileNotFoundException if fileName is not readable, 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not a file, or not present. 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.io.IOException if fileName is not a valid apk/jar file or 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if problems occur while parsing it. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.lang.NullPointerException if fileName is null. 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws dalvik.system.StaleDexCacheError if the optimized dex file 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is stale but exists on a read-only partition. 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project native public static boolean isDexOptNeeded(String fileName) 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws FileNotFoundException, IOException; 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 303