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