112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden/*
212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Copyright (C) 2009 The Android Open Source Project
312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden *
412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * you may not use this file except in compliance with the License.
612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * You may obtain a copy of the License at
712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden *
812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden *
1012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Unless required by applicable law or agreed to in writing, software
1112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
1212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * See the License for the specific language governing permissions and
1412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * limitations under the License.
1512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */
1612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
1712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenpackage com.android.dexdeps;
1812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
1912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.File;
2012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.FileNotFoundException;
2112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.IOException;
2212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.InputStream;
2312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.RandomAccessFile;
2412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipEntry;
2512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipException;
2612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipFile;
2712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipInputStream;
2812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
2912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenpublic class Main {
3012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    private static final String CLASSES_DEX = "classes.dex";
3112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
3206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein    private String[] mInputFileNames;
3300da1fe5d42693f2bcf5351a459db1fb32b9ca9cAndy McFadden    private String mOutputFormat = "xml";
3412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
3512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    /**
3606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     * whether to only emit info about classes used; when {@code false},
3706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     * info about fields and methods is also emitted
3806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     */
3906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein    private boolean mJustClasses = false;
4006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein
4106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein    /**
4212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * Entry point.
4312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     */
4412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    public static void main(String[] args) {
4512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        Main main = new Main();
4612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        main.run(args);
4712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    }
4812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
4912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    /**
5012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * Start things up.
5112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     */
5212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    void run(String[] args) {
5312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        try {
5412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            parseArgs(args);
5506d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            boolean first = true;
5606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein
5706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            for (String fileName : mInputFileNames) {
5806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                RandomAccessFile raf = openInputFile(fileName);
5906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                DexData dexData = new DexData(raf);
6006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                dexData.load();
6106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein
6206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                if (first) {
6306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                    first = false;
6406d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                    Output.generateFirstHeader(fileName, mOutputFormat);
6506d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                } else {
6606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                    Output.generateHeader(fileName, mOutputFormat);
6706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                }
6812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
6906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                Output.generate(dexData, mOutputFormat, mJustClasses);
7006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                Output.generateFooter(mOutputFormat);
7106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                raf.close();
7206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            }
7312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        } catch (UsageException ue) {
7412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            usage();
7512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            System.exit(2);
7612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        } catch (IOException ioe) {
7706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            if (ioe.getMessage() != null) {
78753f32ab1db6de174a1de68210f9f30a1e327612Andy McFadden                System.err.println("Failed: " + ioe);
7906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            }
8012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            System.exit(1);
8112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        } catch (DexDataException dde) {
8212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            /* a message was already reported, just bail quietly */
8312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            System.exit(1);
8412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
8512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    }
8612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
8712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    /**
8806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     * Opens an input file, which could be a .dex or a .jar/.apk with a
8912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * classes.dex inside.  If the latter, we extract the contents to a
9012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * temporary file.
9106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     *
9206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     * @param fileName the name of the file to open
9312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     */
9406d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein    RandomAccessFile openInputFile(String fileName) throws IOException {
9512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        RandomAccessFile raf;
9612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
9706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        raf = openInputFileAsZip(fileName);
9812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        if (raf == null) {
9906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            File inputFile = new File(fileName);
10012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            raf = new RandomAccessFile(inputFile, "r");
10112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
10212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
10312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        return raf;
10412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    }
10512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
10612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    /**
10706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     * Tries to open an input file as a Zip archive (jar/apk) with a
10812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * "classes.dex" inside.
10912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     *
11006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein     * @param fileName the name of the file to open
11112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * @return a RandomAccessFile for classes.dex, or null if the input file
11212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     *         is not a zip archive
11312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * @throws IOException if the file isn't found, or it's a zip and
11412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     *         classes.dex isn't found inside
11512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     */
11606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein    RandomAccessFile openInputFileAsZip(String fileName) throws IOException {
11712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        ZipFile zipFile;
11812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
11912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        /*
12012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * Try it as a zip file.
12112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         */
12212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        try {
12306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            zipFile = new ZipFile(fileName);
12412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        } catch (FileNotFoundException fnfe) {
12512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            /* not found, no point in retrying as non-zip */
12606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            System.err.println("Unable to open '" + fileName + "': " +
12712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                fnfe.getMessage());
12812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            throw fnfe;
12912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        } catch (ZipException ze) {
13012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            /* not a zip */
13112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            return null;
13212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
13312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
13412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        /*
13512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * We know it's a zip; see if there's anything useful inside.  A
13612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * failure here results in some type of IOException (of which
13712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * ZipException is a subclass).
13812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         */
13912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        ZipEntry entry = zipFile.getEntry(CLASSES_DEX);
14012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        if (entry == null) {
14112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            System.err.println("Unable to find '" + CLASSES_DEX +
14206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "' in '" + fileName + "'");
14312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            zipFile.close();
14412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            throw new ZipException();
14512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
14612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
14712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        InputStream zis = zipFile.getInputStream(entry);
14812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
14912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        /*
15012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * Create a temp file to hold the DEX data, open it, and delete it
15112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * to ensure it doesn't hang around if we fail.
15212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         */
15312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        File tempFile = File.createTempFile("dexdeps", ".dex");
154753f32ab1db6de174a1de68210f9f30a1e327612Andy McFadden        //System.out.println("+++ using temp " + tempFile);
15512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
15612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        tempFile.delete();
15712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
15812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        /*
15912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         * Copy all data from input stream to output file.
16012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden         */
16112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        byte copyBuf[] = new byte[32768];
16212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        int actual;
16312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
16412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        while (true) {
16512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            actual = zis.read(copyBuf);
16612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            if (actual == -1)
16712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                break;
16812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
16912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            raf.write(copyBuf, 0, actual);
17012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
17112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
17212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        zis.close();
17312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        raf.seek(0);
17412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
17512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        return raf;
17612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    }
17712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
17812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
17912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    /**
18012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * Parses command-line arguments.
18112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     *
18212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * @throws UsageException if arguments are missing or poorly formed
18312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     */
18412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    void parseArgs(String[] args) {
18512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        int idx;
18612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
18712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        for (idx = 0; idx < args.length; idx++) {
18812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            String arg = args[idx];
18912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
19012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            if (arg.equals("--") || !arg.startsWith("--")) {
19112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                break;
19212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            } else if (arg.startsWith("--format=")) {
19312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                mOutputFormat = arg.substring(arg.indexOf('=') + 1);
19412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                if (!mOutputFormat.equals("brief") &&
19512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                    !mOutputFormat.equals("xml"))
19612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                {
19712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                    System.err.println("Unknown format '" + mOutputFormat +"'");
19812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                    throw new UsageException();
19912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                }
200753f32ab1db6de174a1de68210f9f30a1e327612Andy McFadden                //System.out.println("+++ using format " + mOutputFormat);
20106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein            } else if (arg.equals("--just-classes")) {
20206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                mJustClasses = true;
20312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            } else {
20412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                System.err.println("Unknown option '" + arg + "'");
20512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden                throw new UsageException();
20612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            }
20712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
20812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
20906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        // We expect at least one more argument (file name).
21006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        int fileCount = args.length - idx;
21106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        if (fileCount == 0) {
21212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden            throw new UsageException();
21312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden        }
21412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
21506d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        mInputFileNames = new String[fileCount];
21606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        System.arraycopy(args, idx, mInputFileNames, 0, fileCount);
21712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    }
21812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden
21912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    /**
22012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     * Prints command-line usage info.
22112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden     */
22212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    void usage() {
22306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein        System.err.print(
22406d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "DEX dependency scanner v1.2\n" +
22506d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "Copyright (C) 2009 The Android Open Source Project\n\n" +
22606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "Usage: dexdeps [options] <file.{dex,apk,jar}> ...\n" +
22706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "Options:\n" +
22806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "  --format={xml,brief}\n" +
22906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein                "  --just-classes\n");
23012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden    }
23112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden}
232