Home | History | Annotate | Download | only in apicoverage
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.apicoverage;
     18 
     19 
     20 import org.xml.sax.SAXException;
     21 
     22 import java.io.File;
     23 import java.io.FileOutputStream;
     24 import java.io.FilenameFilter;
     25 import java.io.IOException;
     26 import java.io.InputStream;
     27 import java.util.ArrayList;
     28 import java.util.Enumeration;
     29 import java.util.HashMap;
     30 import java.util.List;
     31 import java.util.Map;
     32 import java.util.zip.ZipEntry;
     33 import java.util.zip.ZipFile;
     34 /**
     35  * Class that outputs an XML report of the {@link ApiCoverage} collected. It can be viewed in a
     36  * browser when used with the api-coverage.css and api-coverage.xsl files.
     37  */
     38 class ApkNdkApiReport {
     39     public static final String FILE_FILTER_EXT = ".apk";
     40     public static final String DEFAULT_OUTPUT_FILE_NAME = "./apk-ndk-coverage.txt";
     41 
     42     private static final FilenameFilter SUPPORTED_FILE_NAME_FILTER =
     43             new FilenameFilter() {
     44                 public boolean accept(File dir, String name) {
     45                     String fileName = name.toLowerCase();
     46                     return fileName.endsWith(FILE_FILTER_EXT);
     47                 }
     48             };
     49 
     50     private static void printUsage() {
     51         System.out.println("Usage: ApkNdkApiReport [OPTION]... [APK]...");
     52         System.out.println();
     53         System.out.println("Generates a report about what Android NDK methods.");
     54         System.out.println();
     55         System.out.println("Options:");
     56         System.out.println("  -o FILE                output file or standard out if not given");
     57         System.out.println("  -t PATH                path to the CTS testcases Folder");
     58         System.out.println("  -b BITS                64 or 32");
     59         System.out.println();
     60         System.exit(1);
     61     }
     62 
     63     /** Get the argument or print out the usage and exit. */
     64     private static String getExpectedArg(String[] args, int index) {
     65         if (index < args.length) {
     66             return args[index];
     67         } else {
     68             printUsage();
     69             return null; // Never will happen because printUsage will call exit(1)
     70         }
     71     }
     72 
     73     public static void main(String[] args) throws IOException, SAXException {
     74         ApkNdkApiReport apiReport;
     75         String testCasePath = "";
     76         String bits = "64";
     77         String outputFileName = DEFAULT_OUTPUT_FILE_NAME;
     78         int numTestModule = 0;
     79 
     80         for (int i = 0; i < args.length; i++) {
     81             if (args[i].startsWith("-")) {
     82                 if ("-o".equals(args[i])) {
     83                     outputFileName = getExpectedArg(args, ++i);
     84                 } else if ("-t".equals(args[i])) {
     85                     testCasePath = getExpectedArg(args, ++i);
     86                 } else if ("-b".equals(args[i])) {
     87                     bits = getExpectedArg(args, ++i);
     88                 } else {
     89                     printUsage();
     90                 }
     91             } else {
     92                 printUsage();
     93             }
     94         }
     95 
     96         apiReport = parseTestcasesFolder(testCasePath, bits);
     97         if (apiReport != null) {
     98             for (TestModule tm : apiReport.mTestModules) {
     99                 tm.getDynSymArr();
    100             }
    101         } else {
    102             printUsage();
    103         }
    104     }
    105 
    106     private List<TestModule> mTestModules;
    107     private String mBits;
    108 
    109     ApkNdkApiReport(List<TestModule> testModules, String bits) {
    110         mTestModules = testModules;
    111         mBits = bits;
    112     }
    113 
    114     public List<TestModule> getTestModules() {
    115         return mTestModules;
    116     }
    117 
    118     public String getBits() {
    119         return mBits;
    120     }
    121 
    122     public static ApkNdkApiReport parseTestcasesFolder(String testCasePath, String bits)
    123             throws IOException, SAXException {
    124         File[] testConfigFiles;
    125         List<TestModule> testModules = new ArrayList<TestModule>();
    126 
    127         File file = new File(testCasePath);
    128         if (file.isDirectory()) {
    129             File[] targetFiles = file.listFiles(SUPPORTED_FILE_NAME_FILTER);
    130 
    131             Map<String, String> env = new HashMap<>();
    132             for (File targetFile : targetFiles) {
    133                 final ZipFile apkFile = new ZipFile(targetFile);
    134                 System.out.println(targetFile.getName());
    135                 try {
    136                     final Enumeration<? extends ZipEntry> entries = apkFile.entries();
    137                     while (entries.hasMoreElements()) {
    138                         final ZipEntry entry = entries.nextElement();
    139 
    140                         if (!entry.getName().matches("lib(.*)" + bits + "(.*)so")) {
    141                             continue;
    142                         }
    143 
    144                         System.out.println(entry.getName());
    145 
    146                         //use entry input stream:
    147                         InputStream is = apkFile.getInputStream(entry);
    148 
    149                         File tempFile = File.createTempFile("ApkNdkApiReport", ".so");
    150                         tempFile.deleteOnExit();
    151                         FileOutputStream fos = new FileOutputStream(tempFile);
    152 
    153                         byte[] bytes = new byte[4096];
    154                         int length;
    155                         while ((length = is.read(bytes)) >= 0) {
    156                             fos.write(bytes, 0, length);
    157                         }
    158                         is.close();
    159                         fos.close();
    160 
    161                         testModules.add(new TestModule(tempFile, targetFile.getName(), "jUnit"));
    162                     }
    163                 } catch (IOException e) {
    164                     e.printStackTrace();
    165                 }
    166             }
    167         } else {
    168             return null;
    169         }
    170         return new ApkNdkApiReport(testModules, bits);
    171     }
    172 }
    173