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