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 = "Usage: "
31         + "manifest-generator -n NAME -p PACKAGE_NAME -o OUTPUT_FILE -i INSTRUMENT_NAME "
32         + "[-s MIN_SDK_VERSION] [-t TARGET_SDK_VERSION] [-r PERMISSION]+ [-a ACTIVITY]+";
33     private static final String MANIFEST = "manifest";
34     private static final String USES_SDK = "uses-sdk";
35     private static final String USES_PERMISSION = "uses-permission";
36     private static final String APPLICATION = "application";
37     private static final String INSTRUMENTATION = "instrumentation";
38     private static final String ACTIVITY = "activity";
39 
main(String[] args)40     public static void main(String[] args) {
41         String pkgName = null;
42         String instrumentName = null;
43         String minSdk = DEFAULT_MIN_SDK;
44         String targetSdk = null;
45         List<String> permissions = new ArrayList<>();
46         List<String> activities = new ArrayList<>();
47         String output = null;
48 
49         for (int i = 0; i < args.length - 1; i++) {
50             if (args[i].equals("-p")) {
51                 pkgName = args[++i];
52             } else if (args[i].equals("-a")) {
53                 activities.add(args[++i]);
54             } else if (args[i].equals("-o")) {
55                 output = args[++i];
56             } else if (args[i].equals("-i")) {
57                 instrumentName = args[++i];
58             } else if (args[i].equals("-r")) {
59                 permissions.add(args[++i]);
60             } else if (args[i].equals("-s")) {
61                 minSdk = args[++i];
62             } else if (args[i].equals("-t")) {
63                 targetSdk = args[++i];
64             }
65         }
66 
67         if (pkgName == null) {
68             error("Missing package name");
69         } else if (instrumentName == null) {
70             error("Missing instrumentation name");
71         } else if (activities.isEmpty()) {
72             error("No activities");
73         } else if (output == null) {
74             error("Missing output file");
75         }
76 
77         FileOutputStream out = null;
78         try {
79           out = new FileOutputStream(output);
80           generate(out, pkgName, instrumentName, minSdk, targetSdk, permissions, activities);
81         } catch (Exception e) {
82           System.err.println("Couldn't create manifest file");
83         } finally {
84           if (out != null) {
85               try {
86                   out.close();
87               } catch (Exception e) {
88                   // Ignore
89               }
90           }
91         }
92     }
93 
generate(OutputStream out, String pkgName, String instrumentName, String minSdk, String targetSdk, List<String> permissions, List<String> activities)94     /*package*/ static void generate(OutputStream out, String pkgName, String instrumentName,
95             String minSdk, String targetSdk, List<String> permissions, List<String> activities)
96             throws Exception {
97         final String ns = null;
98         KXmlSerializer serializer = new KXmlSerializer();
99         serializer.setOutput(out, "UTF-8");
100         serializer.startDocument("UTF-8", true);
101         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
102         serializer.startTag(ns, MANIFEST);
103         serializer.attribute(ns, "xmlns:android", "http://schemas.android.com/apk/res/android");
104         serializer.attribute(ns, "package", pkgName);
105         serializer.startTag(ns, USES_SDK);
106         serializer.attribute(ns, "android:minSdkVersion", minSdk);
107         if (targetSdk != null) {
108             serializer.attribute(ns, "android:targetSdkVersion", targetSdk);
109         }
110         serializer.endTag(ns, USES_SDK);
111         for (String permission : permissions) {
112             serializer.startTag(ns, USES_PERMISSION);
113             serializer.attribute(ns, "android:name", permission);
114             serializer.endTag(ns, USES_PERMISSION);
115         }
116         serializer.startTag(ns, APPLICATION);
117         for (String activity : activities) {
118             serializer.startTag(ns, ACTIVITY);
119             serializer.attribute(ns, "android:name", activity);
120             serializer.endTag(ns, ACTIVITY);
121         }
122         serializer.endTag(ns, APPLICATION);
123         serializer.startTag(ns, INSTRUMENTATION);
124         serializer.attribute(ns, "android:name", instrumentName);
125         serializer.attribute(ns, "android:targetPackage", pkgName);
126         serializer.endTag(ns, INSTRUMENTATION);
127         serializer.endTag(ns, MANIFEST);
128         serializer.endDocument();
129         out.flush();
130     }
131 
error(String message)132     private static void error(String message) {
133         System.err.println(message);
134         System.err.println(USAGE);
135         System.exit(1);
136     }
137 }
138