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