1 /*
2  * Copyright (C) 2015 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.compatibility.common.generator;
18 
19 import java.io.FileOutputStream;
20 import java.io.OutputStream;
21 import java.util.ArrayList;
22 import java.util.List;
23 
24 import org.kxml2.io.KXmlSerializer;
25 
26 public class ManifestGenerator {
27 
28     private static final String DEFAULT_MIN_SDK = "8";
29 
30     private static final String USAGE =
31             "Usage: manifest-generator -n NAME -p PACKAGE_NAME -o OUTPUT_FILE -i INSTRUMENT_NAME "
32                     + "[-s MIN_SDK_VERSION] [-t TARGET_SDK_VERSION] [-r PERMISSION]+ "
33                     + "[-a ACTIVITY]+ [-l REQUIRED_LIBRARY]+ [-lo OPTIONAL_LIBRARY]+";
34     private static final String MANIFEST = "manifest";
35     private static final String USES_SDK = "uses-sdk";
36     private static final String USES_PERMISSION = "uses-permission";
37     private static final String APPLICATION = "application";
38     private static final String INSTRUMENTATION = "instrumentation";
39     private static final String ACTIVITY = "activity";
40     private static final String USES_LIBRARY = "uses-library";
41 
main(String[] args)42     public static void main(String[] args) {
43         String pkgName = null;
44         String instrumentName = null;
45         String minSdk = DEFAULT_MIN_SDK;
46         String targetSdk = null;
47         List<String> permissions = new ArrayList<>();
48         List<String> activities = new ArrayList<>();
49         List<String> libraries = new ArrayList<>();
50         List<String> optionalLibs = new ArrayList<>();
51         String output = null;
52 
53         for (int i = 0; i < args.length - 1; i++) {
54             if (args[i].equals("-p")) {
55                 pkgName = args[++i];
56             } else if (args[i].equals("-a")) {
57                 activities.add(args[++i]);
58             } else if (args[i].equals("-l")) {
59                 libraries.add(args[++i]);
60             } else if (args[i].equals("-lo")) {
61                 optionalLibs.add(args[++i]);
62             } else if (args[i].equals("-o")) {
63                 output = args[++i];
64             } else if (args[i].equals("-i")) {
65                 instrumentName = args[++i];
66             } else if (args[i].equals("-r")) {
67                 permissions.add(args[++i]);
68             } else if (args[i].equals("-s")) {
69                 minSdk = args[++i];
70             } else if (args[i].equals("-t")) {
71                 targetSdk = args[++i];
72             }
73         }
74 
75         if (pkgName == null) {
76             error("Missing package name");
77         } else if (instrumentName == null) {
78             error("Missing instrumentation name");
79         } else if (activities.isEmpty()) {
80             error("No activities");
81         } else if (output == null) {
82             error("Missing output file");
83         }
84 
85         FileOutputStream out = null;
86         try {
87             out = new FileOutputStream(output);
88             generate(
89                     out,
90                     pkgName,
91                     instrumentName,
92                     minSdk,
93                     targetSdk,
94                     permissions,
95                     activities,
96                     libraries,
97                     optionalLibs);
98         } catch (Exception e) {
99             System.err.println("Couldn't create manifest file");
100         } finally {
101             if (out != null) {
102                 try {
103                     out.close();
104                 } catch (Exception e) {
105                     // Ignore
106                 }
107             }
108         }
109     }
110 
generate( OutputStream out, String pkgName, String instrumentName, String minSdk, String targetSdk, List<String> permissions, List<String> activities, List<String> libraries, List<String> optionalLibs)111     /*package*/ static void generate(
112             OutputStream out,
113             String pkgName,
114             String instrumentName,
115             String minSdk,
116             String targetSdk,
117             List<String> permissions,
118             List<String> activities,
119             List<String> libraries,
120             List<String> optionalLibs)
121             throws Exception {
122         final String ns = null;
123         KXmlSerializer serializer = new KXmlSerializer();
124         serializer.setOutput(out, "UTF-8");
125         serializer.startDocument("UTF-8", true);
126         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
127         serializer.startTag(ns, MANIFEST);
128         serializer.attribute(ns, "xmlns:android", "http://schemas.android.com/apk/res/android");
129         serializer.attribute(ns, "package", pkgName);
130         serializer.startTag(ns, USES_SDK);
131         serializer.attribute(ns, "android:minSdkVersion", minSdk);
132         if (targetSdk != null) {
133             serializer.attribute(ns, "android:targetSdkVersion", targetSdk);
134         }
135         serializer.endTag(ns, USES_SDK);
136         for (String permission : permissions) {
137             serializer.startTag(ns, USES_PERMISSION);
138             serializer.attribute(ns, "android:name", permission);
139             serializer.endTag(ns, USES_PERMISSION);
140         }
141         serializer.startTag(ns, APPLICATION);
142         for (String library : libraries) {
143             serializer.startTag(ns, USES_LIBRARY);
144             serializer.attribute(ns, "android:name", library);
145             serializer.endTag(ns, USES_LIBRARY);
146         }
147         for (String optionalLib : optionalLibs) {
148             serializer.startTag(ns, USES_LIBRARY);
149             serializer.attribute(ns, "android:name", optionalLib);
150             serializer.attribute(ns, "android:required", "false");
151             serializer.endTag(ns, USES_LIBRARY);
152         }
153         for (String activity : activities) {
154             serializer.startTag(ns, ACTIVITY);
155             serializer.attribute(ns, "android:name", activity);
156             serializer.endTag(ns, ACTIVITY);
157         }
158         serializer.endTag(ns, APPLICATION);
159         serializer.startTag(ns, INSTRUMENTATION);
160         serializer.attribute(ns, "android:name", instrumentName);
161         serializer.attribute(ns, "android:targetPackage", pkgName);
162         serializer.endTag(ns, INSTRUMENTATION);
163         serializer.endTag(ns, MANIFEST);
164         serializer.endDocument();
165         out.flush();
166     }
167 
error(String message)168     private static void error(String message) {
169         System.err.println(message);
170         System.err.println(USAGE);
171         System.exit(1);
172     }
173 }
174