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