• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
printUsage()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. */
getExpectedArg(String[] args, int index)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 
main(String[] args)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 
ApkNdkApiReport(List<TestModule> testModules, String bits)109     ApkNdkApiReport(List<TestModule> testModules, String bits) {
110         mTestModules = testModules;
111         mBits = bits;
112     }
113 
getTestModules()114     public List<TestModule> getTestModules() {
115         return mTestModules;
116     }
117 
getBits()118     public String getBits() {
119         return mBits;
120     }
121 
parseTestcasesFolder(String testCasePath, String bits)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