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 195d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport android.system.ErrnoException; 20e31b37859051d3902e06e4ba384995df7188917fHans Boehmimport dalvik.annotation.optimization.ReachabilitySensitive; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.File; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileNotFoundException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 2457dfd7182e6d169ec5a195ab03900a323b27ea13Alex Lightimport java.nio.ByteBuffer; 2557dfd7182e6d169ec5a195ab03900a323b27ea13Alex Lightimport java.util.Arrays; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 276c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstromimport java.util.List; 285c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilsonimport libcore.io.Libcore; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 31ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * Loads DEX files. This class is meant for internal use and should not be used 32ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * by applications. 33ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * 34ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * @deprecated This class should not be used directly by applications. It will hurt 35ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * performance in most cases and will lead to incorrect execution of bytecode in 36ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * the worst case. Applications should use one of the standard classloaders such 37ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * as {@link dalvik.system.PathClassLoader} instead. <b>This API will be removed 38ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * in a future Android release</b>. 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 40ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath@Deprecated 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class DexFile { 42615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier /** 43615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier * If close is called, mCookie becomes null but the internal cookie is preserved if the close 44615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier * failed so that we can free resources in the finalizer. 45615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier */ 46e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 4725ac148a433feee2972fb01655a3f7ed4956c1f8Andreas Gampe private Object mCookie; 48e31b37859051d3902e06e4ba384995df7188917fHans Boehm 49615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier private Object mInternalCookie; 50f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom private final String mFileName; 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 53ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * Opens a DEX file from a given File object. 54f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 55ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * @deprecated Applications should use one of the standard classloaders such 56ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * as {@link dalvik.system.PathClassLoader} instead. <b>This API will be removed 57ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * in a future Android release</b>. 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 59ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath @Deprecated 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DexFile(File file) throws IOException { 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(file.getPath()); 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 6370fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier /* 6470fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * Private version with class loader argument. 6570fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * 6670fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param file 6770fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * the File object referencing the actual DEX file 6870fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param loader 6970fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * the class loader object creating the DEX file object 70da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * @param elements 71da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * the temporary dex path list elements from DexPathList.makeElements 7270fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier */ 73da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier DexFile(File file, ClassLoader loader, DexPathList.Element[] elements) 74da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier throws IOException { 75da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier this(file.getPath(), loader, elements); 7670fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 79ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * Opens a DEX file from a given filename. 80f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 81ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * @deprecated Applications should use one of the standard classloaders such 82ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * as {@link dalvik.system.PathClassLoader} instead. <b>This API will be removed 83ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * in a future Android release</b>. 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 85ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath @Deprecated 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DexFile(String fileName) throws IOException { 87da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier this(fileName, null, null); 8870fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier } 8970fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier 9070fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier /* 9170fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * Private version with class loader argument. 9270fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * 9370fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param fileName 9470fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * the filename of the DEX file 9570fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param loader 9670fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * the class loader creating the DEX file object 97da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * @param elements 98da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * the temporary dex path list elements from DexPathList.makeElements 9970fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier */ 100da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier DexFile(String fileName, ClassLoader loader, DexPathList.Element[] elements) throws IOException { 101da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier mCookie = openDexFile(fileName, null, 0, loader, elements); 102615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier mInternalCookie = mCookie; 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mFileName = fileName; 104e606e1e9f44853b226caab6fa13c041033a49e09Brian Carlstrom //System.out.println("DEX FILE cookie is " + mCookie + " fileName=" + fileName); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10757dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light DexFile(ByteBuffer buf) throws IOException { 10857dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light mCookie = openInMemoryDexFile(buf); 10957dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light mInternalCookie = mCookie; 11057dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light mFileName = null; 11157dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light } 11257dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Opens a DEX file from a given filename, using a specified file 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to hold the optimized data. 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sourceName 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Jar or APK file with "classes.dex". 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputName 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * File that will hold the optimized form of the DEX data. 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param flags 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enable optional features. 12370fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param loader 12470fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * The class loader creating the DEX file object. 125da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * @param elements 126da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * The temporary dex path list elements from DexPathList.makeElements 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 128da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier private DexFile(String sourceName, String outputName, int flags, ClassLoader loader, 129da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier DexPathList.Element[] elements) throws IOException { 1305c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson if (outputName != null) { 1315c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson try { 1325c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson String parent = new File(outputName).getParent(); 1335c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson if (Libcore.os.getuid() != Libcore.os.stat(parent).st_uid) { 1345c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson throw new IllegalArgumentException("Optimized data directory " + parent 1355c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson + " is not owned by the current user. Shared storage cannot protect" 1365c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson + " your application from code injection attacks."); 1375c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } 1385c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } catch (ErrnoException ignored) { 1395c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson // assume we'll fail with a more contextual error later 1405c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } 1415c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson } 1425c7fa7c36acddda7b7cc392ec360116b03e09880Jesse Wilson 143da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier mCookie = openDexFile(sourceName, outputName, flags, loader, elements); 1443ebd936564d7b2639b9ec124274b89e4e36a85f5Anton Kirilov mInternalCookie = mCookie; 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mFileName = sourceName; 146e606e1e9f44853b226caab6fa13c041033a49e09Brian Carlstrom //System.out.println("DEX FILE cookie is " + mCookie + " sourceName=" + sourceName + " outputName=" + outputName); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Open a DEX file, specifying the file in which the optimized DEX 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * data should be written. If the optimized form exists and appears 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to be current, it will be used; if not, the VM will attempt to 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * regenerate it. 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 155ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * @deprecated Applications should use one of the standard classloaders such 156ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * as {@link dalvik.system.PathClassLoader} instead. <b>This API will be removed 157ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath * in a future Android release</b>. 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 159ad25a60fb6799976654a8e3841c79992de394ebcNarayan Kamath @Deprecated 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static public DexFile loadDex(String sourcePathName, String outputPathName, 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int flags) throws IOException { 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TODO: we may want to cache previously-opened DexFile objects. 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cache would be synchronized with close(). This would help 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * us avoid mapping the same DEX more than once when an app 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decided to open it multiple times. In practice this may not 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be a real issue. 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier return loadDex(sourcePathName, outputPathName, flags, null, null); 17170fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier } 17270fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier 17370fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier /* 17470fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * Private version of loadDex that also takes a class loader. 17570fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * 17670fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param sourcePathName 17770fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * Jar or APK file with "classes.dex". (May expand this to include 17870fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * "raw DEX" in the future.) 17970fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param outputPathName 18070fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * File that will hold the optimized form of the DEX data. 18170fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param flags 18270fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * Enable optional features. (Currently none defined.) 18370fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @param loader 18470fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * Class loader that is aloading the DEX file. 185da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * @param elements 186da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier * The temporary dex path list elements from DexPathList.makeElements 18770fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @return 18870fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * A new or previously-opened DexFile. 18970fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * @throws IOException 19070fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * If unable to open the source or output file. 19170fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier */ 19270fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier static DexFile loadDex(String sourcePathName, String outputPathName, 193da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException { 19470fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier 19570fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier /* 19670fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * TODO: we may want to cache previously-opened DexFile objects. 19770fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * The cache would be synchronized with close(). This would help 19870fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * us avoid mapping the same DEX more than once when an app 19970fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * decided to open it multiple times. In practice this may not 20070fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier * be a real issue. 20170fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier */ 202da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier return new DexFile(sourcePathName, outputPathName, flags, loader, elements); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the name of the (already opened) DEX file. 207f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the file name 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return mFileName; 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 214e606e1e9f44853b226caab6fa13c041033a49e09Brian Carlstrom @Override public String toString() { 21557dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light if (mFileName != null) { 21657dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light return getName(); 21757dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light } else { 21857dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light return "InMemoryDexFile[cookie=" + Arrays.toString((long[]) mCookie) + "]"; 21957dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light } 220e606e1e9f44853b226caab6fa13c041033a49e09Brian Carlstrom } 221e606e1e9f44853b226caab6fa13c041033a49e09Brian Carlstrom 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the DEX file. 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 225615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier * This may not be able to release all of the resources. If classes from this DEX file are 226615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier * still resident, the DEX file can't be unmapped. In the case where we do not release all 227615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier * the resources, close is called again in the finalizer. 228f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs during closing the file, which 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * normally should not happen 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 234615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier if (mInternalCookie != null) { 235615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier if (closeDexFile(mInternalCookie)) { 236615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier mInternalCookie = null; 237615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier } 23825ac148a433feee2972fb01655a3f7ed4956c1f8Andreas Gampe mCookie = null; 2396c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Loads a class. Returns the class on success, or a {@code null} reference 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on failure. 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If you are not calling this from a class loader, this is most likely not 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * going to do what you want. Use {@link Class#forName(String)} instead. 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The method does not throw {@link ClassNotFoundException} if the class 250be9c142fd80574e5d15571dad2562cd6894e2c81Andy McFadden * isn't found because it isn't reasonable to throw exceptions wildly every 251be9c142fd80574e5d15571dad2562cd6894e2c81Andy McFadden * time a class is not found in the first DEX file we look at. 252f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class name, which should look like "java/lang/String" 255f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loader 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class loader that tries to load the class (in most cases 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the caller of the method 259f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@link Class} object representing the class, or {@code null} 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class cannot be loaded 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Class loadClass(String name, ClassLoader loader) { 2640fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden String slashName = name.replace('.', '/'); 2656c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom return loadClassBinaryName(slashName, loader, null); 2660fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden } 2670fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden 2680fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden /** 2690fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * See {@link #loadClass(String, ClassLoader)}. 2700fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * 2710fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * This takes a "binary" class name to better match ClassLoader semantics. 2720fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden * 273fb374e129dc73d4adafc9441ca78011676a26d9fCarl Shapiro * @hide 2740fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden */ 2756c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed) { 2762f7ca12a42b05999820bd9cce1882beeb109838eMathieu Chartier return defineClass(name, loader, mCookie, this, suppressed); 2776c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } 2786c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom 27925ac148a433feee2972fb01655a3f7ed4956c1f8Andreas Gampe private static Class defineClass(String name, ClassLoader loader, Object cookie, 2802f7ca12a42b05999820bd9cce1882beeb109838eMathieu Chartier DexFile dexFile, List<Throwable> suppressed) { 2816c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom Class result = null; 2826c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom try { 2832f7ca12a42b05999820bd9cce1882beeb109838eMathieu Chartier result = defineClassNative(name, loader, cookie, dexFile); 2846c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } catch (NoClassDefFoundError e) { 2856c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom if (suppressed != null) { 2866c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom suppressed.add(e); 2876c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } 2886c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } catch (ClassNotFoundException e) { 2896c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom if (suppressed != null) { 2906c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom suppressed.add(e); 2916c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } 2926c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom } 2936c290d33a3585654db0500dabf5f937985e5b15dBrian Carlstrom return result; 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2950fb831a410412728d6ee79ff98c465233b0803d0Andy McFadden 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enumerate the names of the classes in this DEX file. 298f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an enumeration of names of classes contained in the DEX file, in 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the usual internal form (like "java/lang/String"). 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Enumeration<String> entries() { 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new DFEnum(this); 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Helper class. 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 3092da86235d031fe655e571c10f69b60f053841884Tobias Thierer private static class DFEnum implements Enumeration<String> { 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int mIndex; 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String[] mNameList; 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DFEnum(DexFile df) { 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mIndex = 0; 3152da86235d031fe655e571c10f69b60f053841884Tobias Thierer mNameList = getClassNameList(df.mCookie); 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasMoreElements() { 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (mIndex < mNameList.length); 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String nextElement() { 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return mNameList[mIndex++]; 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 327f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes /** 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Called when the class is finalized. Makes sure the DEX file is closed. 329f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs during closing the file, which 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * normally should not happen 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 334e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 335e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 336615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier if (mInternalCookie != null && !closeDexFile(mInternalCookie)) { 337615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier throw new AssertionError("Failed to close dex file in finalizer."); 338615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier } 339615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier mInternalCookie = null; 340615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier mCookie = null; 341e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 342e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 343e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 346e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle 347e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle /* 348e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle * Open a DEX file. The value returned is a magic VM cookie. On 349e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle * failure, an IOException is thrown. 350e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle */ 35170fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier private static Object openDexFile(String sourceName, String outputName, int flags, 352da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier ClassLoader loader, DexPathList.Element[] elements) throws IOException { 353e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle // Use absolute paths to enable the use of relative paths when testing on host. 354e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle return openDexFileNative(new File(sourceName).getAbsolutePath(), 35570fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier (outputName == null) 35670fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier ? null 35770fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier : new File(outputName).getAbsolutePath(), 35870fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier flags, 359da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier loader, 360da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier elements); 361e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle } 362e05ad6f7a1e2e34db62587269a066d479dc8e0adCalin Juravle 36357dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light private static Object openInMemoryDexFile(ByteBuffer buf) throws IOException { 36457dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light if (buf.isDirect()) { 36557dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light return createCookieWithDirectBuffer(buf, buf.position(), buf.limit()); 36657dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light } else { 36757dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light return createCookieWithArray(buf.array(), buf.position(), buf.limit()); 36857dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light } 36957dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light } 37057dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light 37157dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light private static native Object createCookieWithDirectBuffer(ByteBuffer buf, int start, int end); 37257dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light private static native Object createCookieWithArray(byte[] buf, int start, int end); 37357dfd7182e6d169ec5a195ab03900a323b27ea13Alex Light 374615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier /* 3754cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao * Returns true if the dex file is backed by a valid oat file. 3764cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao */ 3774cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao /*package*/ boolean isBackedByOatFile() { 3784cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao return isBackedByOatFile(mCookie); 3794cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao } 3804cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao 3814cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao /* 3828a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray * Set the dex file as trusted: it can access hidden APIs of the platform. 3838a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray */ 3848a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray /*package*/ void setTrusted() { 3858a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray setTrusted(mCookie); 3868a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray } 3878a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray 3888a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray /* 389615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier * Returns true if we managed to close the dex file. 390615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier */ 391615e2a347c6993bba30fbdee6b4e858333646f59Mathieu Chartier private static native boolean closeDexFile(Object cookie); 3922f7ca12a42b05999820bd9cce1882beeb109838eMathieu Chartier private static native Class defineClassNative(String name, ClassLoader loader, Object cookie, 3932f7ca12a42b05999820bd9cce1882beeb109838eMathieu Chartier DexFile dexFile) 3946b9829917263ba6ccc8d725d730316bb36c0fc78Elliott Hughes throws ClassNotFoundException, NoClassDefFoundError; 39525ac148a433feee2972fb01655a3f7ed4956c1f8Andreas Gampe private static native String[] getClassNameList(Object cookie); 3964cff4ef2810c54dccdeccf2d9abbbf435ed0524fJeff Hao private static native boolean isBackedByOatFile(Object cookie); 3978a6e580cf8d7b04cadb5eada66c52a3bc4ccb8a0Nicolas Geoffray private static native void setTrusted(Object cookie); 398df641c08eb53f4a1cee031ff7ba490535af3ed5dCalin Juravle /* 399df641c08eb53f4a1cee031ff7ba490535af3ed5dCalin Juravle * Open a DEX file. The value returned is a magic VM cookie. On 400df641c08eb53f4a1cee031ff7ba490535af3ed5dCalin Juravle * failure, an IOException is thrown. 401df641c08eb53f4a1cee031ff7ba490535af3ed5dCalin Juravle */ 40270fcc38e7a03f04864499a7356ae1f1e692b7463Mathieu Chartier private static native Object openDexFileNative(String sourceName, String outputName, int flags, 403da3729f76948e5c7ce5eadbdfc03a0f9fe7d4d83Mathieu Chartier ClassLoader loader, DexPathList.Element[] elements); 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the VM believes that the apk/jar file is out of date 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and should be passed through "dexopt" again. 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param fileName the absolute path to the apk/jar file to examine. 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if dexopt should be called on the file, false otherwise. 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.io.FileNotFoundException if fileName is not readable, 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not a file, or not present. 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.io.IOException if fileName is not a valid apk/jar file or 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if problems occur while parsing it. 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.lang.NullPointerException if fileName is null. 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4176b9829917263ba6ccc8d725d730316bb36c0fc78Elliott Hughes public static native boolean isDexOptNeeded(String fileName) 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws FileNotFoundException, IOException; 4195e51851f6e91f6e5450435b51812e147db8b9735Dave Allison 4205e51851f6e91f6e5450435b51812e147db8b9735Dave Allison /** 421894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * No dexopt should (or can) be done to update the apk/jar. 422894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 42314f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. 42470a89c0f0274ac033785079673ca690ee056eb59Alex Light * 42570a89c0f0274ac033785079673ca690ee056eb59Alex Light * @hide 42670a89c0f0274ac033785079673ca690ee056eb59Alex Light */ 4273bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler public static final int NO_DEXOPT_NEEDED = 0; 42870a89c0f0274ac033785079673ca690ee056eb59Alex Light 42970a89c0f0274ac033785079673ca690ee056eb59Alex Light /** 430894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * dex2oat should be run to update the apk/jar from scratch. 431894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 43214f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. 43370a89c0f0274ac033785079673ca690ee056eb59Alex Light * 43470a89c0f0274ac033785079673ca690ee056eb59Alex Light * @hide 43570a89c0f0274ac033785079673ca690ee056eb59Alex Light */ 436894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public static final int DEX2OAT_FROM_SCRATCH = 1; 43770a89c0f0274ac033785079673ca690ee056eb59Alex Light 43870a89c0f0274ac033785079673ca690ee056eb59Alex Light /** 439894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * dex2oat should be run to update the apk/jar because the existing code 440894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * is out of date with respect to the boot image. 441894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 44214f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. 44370a89c0f0274ac033785079673ca690ee056eb59Alex Light * 44470a89c0f0274ac033785079673ca690ee056eb59Alex Light * @hide 44570a89c0f0274ac033785079673ca690ee056eb59Alex Light */ 446894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public static final int DEX2OAT_FOR_BOOT_IMAGE = 2; 44770a89c0f0274ac033785079673ca690ee056eb59Alex Light 44870a89c0f0274ac033785079673ca690ee056eb59Alex Light /** 449894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * dex2oat should be run to update the apk/jar because the existing code 450894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * is out of date with respect to the target compiler filter. 451894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 45214f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. 4533bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler * 4543bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler * @hide 4553bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler */ 456894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public static final int DEX2OAT_FOR_FILTER = 3; 4573bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler 4585081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle /** 459894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * dex2oat should be run to update the apk/jar because the existing code 4604437a2016858bdf52ac3af5a3c96b8792ede1e66Richard Uhler * is not relocated to match the boot image. 4615081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle * 46214f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}. 4635081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle * 4645081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle * @hide 4655081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle */ 466894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public static final int DEX2OAT_FOR_RELOCATION = 4; 4675081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle 468fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle 469fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle /** 470fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * Calls {@link #getDexOptNeeded(String, String, String, String, String, boolean, boolean)} 471fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * with a null class loader context. 472fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * 473fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * TODO(ngeoffray, calin): deprecate / remove. 474fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * @hide 475fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle */ 476fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle public static int getDexOptNeeded(String fileName, 477fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle String instructionSet, String compilerFilter, boolean newProfile, boolean downgrade) 478fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle throws FileNotFoundException, IOException { 479fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle return getDexOptNeeded( 480fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle fileName, instructionSet, compilerFilter, null, newProfile, downgrade); 481fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle } 482fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle 4833bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler /** 4843bc9b15f175e640b58cd0926f6e208114a693a30Richard Uhler * Returns the VM's opinion of what kind of dexopt is needed to make the 485a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * apk/jar file up to date, where {@code targetMode} is used to indicate what 486a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * type of compilation the caller considers up-to-date, and {@code newProfile} 487a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * is used to indicate whether profile information has changed recently. 48870a89c0f0274ac033785079673ca690ee056eb59Alex Light * 48970a89c0f0274ac033785079673ca690ee056eb59Alex Light * @param fileName the absolute path to the apk/jar file to examine. 490a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * @param compilerFilter a compiler filter to use for what a caller considers up-to-date. 491fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * @param classLoaderContext a string encoding the class loader context the dex file 492fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle * is intended to have at runtime. 493a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * @param newProfile flag that describes whether a profile corresponding 494a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * to the dex file has been recently updated and should be considered 495a32af3610e1a632a4d5262d91e3e6aea06c79d48Andreas Gampe * in the state of the file. 49614f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * @param downgrade flag that describes if the purpose of dexopt is to downgrade the 49714f51143f1688afee1fddce82782c78d35e36977Shubham Ajmera * compiler filter. If set to false, will be evaluated as an upgrade request. 4984437a2016858bdf52ac3af5a3c96b8792ede1e66Richard Uhler * @return NO_DEXOPT_NEEDED, or DEX2OAT_*. See documentation 499894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * of the particular status code for more information on its 500894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * meaning. Returns a positive status code if the status refers to 501894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * the oat file in the oat location. Returns a negative status 502894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * code if the status refers to the oat file in the odex location. 50370a89c0f0274ac033785079673ca690ee056eb59Alex Light * @throws java.io.FileNotFoundException if fileName is not readable, 50470a89c0f0274ac033785079673ca690ee056eb59Alex Light * not a file, or not present. 50570a89c0f0274ac033785079673ca690ee056eb59Alex Light * @throws java.io.IOException if fileName is not a valid apk/jar file or 50670a89c0f0274ac033785079673ca690ee056eb59Alex Light * if problems occur while parsing it. 50770a89c0f0274ac033785079673ca690ee056eb59Alex Light * @throws java.lang.NullPointerException if fileName is null. 50870a89c0f0274ac033785079673ca690ee056eb59Alex Light * 5095e51851f6e91f6e5450435b51812e147db8b9735Dave Allison * @hide 51070a89c0f0274ac033785079673ca690ee056eb59Alex Light */ 5115081919d9bca3d4442b61abde2b8e3c1a67bd693Calin Juravle public static native int getDexOptNeeded(String fileName, 512fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle String instructionSet, String compilerFilter, String classLoaderContext, 513fd86ab6bf5436413d175ef5382a148f65eb1b40cCalin Juravle boolean newProfile, boolean downgrade) 5145e51851f6e91f6e5450435b51812e147db8b9735Dave Allison throws FileNotFoundException, IOException; 5156fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath 5166fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath /** 5176fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath * Returns the status of the dex file {@code fileName}. The returned string is 5186fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath * an opaque, human readable representation of the current status. The output 5196fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath * is only meant for debugging and is not guaranteed to be stable across 5206fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath * releases and/or devices. 5216fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath * 5226fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath * @hide 5236fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath */ 5246fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath public static native String getDexFileStatus(String fileName, String instructionSet) 5256fa389e5d8c5b52ba3ceb6b6c6f4d27e90473856Narayan Kamath throws FileNotFoundException; 526c5046f02819eb8c86d5664ff89a864eedb94bcbbPhilip Cuadra 527c5046f02819eb8c86d5664ff89a864eedb94bcbbPhilip Cuadra /** 5282b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * Encapsulates information about the optimizations performed on a dex file. 5292b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * 5302b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * Note that the info is only meant for debugging and is not guaranteed to be 5312b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * stable across releases and/or devices. 5322b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * 5332b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * @hide 5342b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle */ 5352b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle public static final class OptimizationInfo { 5362b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle // The optimization status. 5372b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle private final String status; 5382b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle // The optimization reason. The reason might be "unknown" if the 5392b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle // the compiler artifacts were not annotated during optimizations. 5402b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle private final String reason; 5412b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle 5422b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle private OptimizationInfo(String status, String reason) { 5432b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle this.status = status; 5442b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle this.reason = reason; 5452b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle } 5462b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle 5472b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle public String getStatus() { 5482b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle return status; 5492b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle } 5502b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle 5512b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle public String getReason() { 5522b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle return reason; 5532b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle } 5542b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle } 5552b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle 5562b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle /** 5572b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * Retrieves the optimization info for a dex file. 5582b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * 5592b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle * @hide 5602b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle */ 5612b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle public static OptimizationInfo getDexFileOptimizationInfo( 5622b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle String fileName, String instructionSet) throws FileNotFoundException { 5632b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle String[] status = getDexFileOptimizationStatus(fileName, instructionSet); 5642b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle return new OptimizationInfo(status[0], status[1]); 5652b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle } 5662b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle 5672b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle /** 56842bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * Returns the optimization status of the dex file {@code fileName}. The returned 56942bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * array will have 2 elements which specify: 57042bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * - index 0: the level of optimizations 57142bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * - index 1: the optimization reason. The reason might be "unknown" if the 57242bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * the compiler artifacts were not annotated during optimizations. 57342bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * 57442bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * The output is only meant for debugging and is not guaranteed to be stable across 57542bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * releases and/or devices. 57642bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * 57742bee246cacff070ad07419b1d1161fd659c986dCalin Juravle * @hide 57842bee246cacff070ad07419b1d1161fd659c986dCalin Juravle */ 5792b9f4f0659c519d95f4bb9b8bf50c289809ee6fcCalin Juravle private static native String[] getDexFileOptimizationStatus( 58042bee246cacff070ad07419b1d1161fd659c986dCalin Juravle String fileName, String instructionSet) throws FileNotFoundException; 58142bee246cacff070ad07419b1d1161fd659c986dCalin Juravle 58242bee246cacff070ad07419b1d1161fd659c986dCalin Juravle /** 5833af6afd0bac24840681be56bb1a70477931cb2dbCalin Juravle * Returns the paths of the optimized files generated for {@code fileName}. 5843af6afd0bac24840681be56bb1a70477931cb2dbCalin Juravle * If no optimized code exists the method returns null. 585c5046f02819eb8c86d5664ff89a864eedb94bcbbPhilip Cuadra * @hide 586c5046f02819eb8c86d5664ff89a864eedb94bcbbPhilip Cuadra */ 5873af6afd0bac24840681be56bb1a70477931cb2dbCalin Juravle public static native String[] getDexFileOutputPaths(String fileName, String instructionSet) 588c5046f02819eb8c86d5664ff89a864eedb94bcbbPhilip Cuadra throws FileNotFoundException; 589894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler 590894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler /** 591894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * Returns whether the given filter is a valid filter. 592894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 593894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * @hide 594894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler */ 595894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public native static boolean isValidCompilerFilter(String filter); 596894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler 597894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler /** 598894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * Returns whether the given filter is based on profiles. 599894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 600894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * @hide 601894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler */ 602894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public native static boolean isProfileGuidedCompilerFilter(String filter); 603894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler 604894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler /** 605894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * Returns the version of the compiler filter that is not based on profiles. 606894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * If the input is not a valid filter, or the filter is already not based on 607894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * profiles, this returns the input. 608894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * 609894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler * @hide 610894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler */ 611894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler public native static String getNonProfileGuidedCompilerFilter(String filter); 612894fb8812d335e3ccb8469319ee425d4b4da79e4Richard Uhler 6136fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray /** 6146fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray * Returns the version of the compiler filter that is suitable for safe mode. 6156fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray * If the input is not a valid filter, or the filter is already suitable for 6166fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray * safe mode, this returns the input. 6176fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray * 6186fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray * @hide 6196fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray */ 6206fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray public native static String getSafeModeCompilerFilter(String filter); 6216fcc968742306f18f2e4046937b162f1a3792998Nicolas Geoffray 6220d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler /** 6230d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * Returns the static file size of the original dex file. 6240d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * The original size of the uncompressed dex file is returned. 6250d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * On device the dex file may be compressed or embedded in some other 6260d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * file (e.g. oat) in a platform implementation dependent manner. This 6270d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * method abstracts away from those details and provides an efficient 6280d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * implementation given that the dex file in question has already been 6290d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * uncompressed, extracted, and/or loaded by the runtime as appropriate. 6300d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * <p> 6310d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * In the case of multidex, returns the sum of the original uncompressed 6320d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * multidex entry file sizes. 6330d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * 6340d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler * @hide 6350d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler */ 6360d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler public long getStaticSizeOfDexFile() { 6370d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler return getStaticSizeOfDexFile(mCookie); 6380d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler } 6390d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler 6400d292fbd065fc2e6c9452563d06b8069440af462Richard Uhler private static native long getStaticSizeOfDexFile(Object cookie); 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 642