1 /* 2 * Copyright (C) 2009 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.ant; 18 19 import com.android.sdklib.internal.project.ApkConfigurationHelper; 20 import com.android.sdklib.internal.project.ApkSettings; 21 import com.android.sdklib.internal.project.ProjectProperties; 22 import com.android.sdklib.internal.project.ProjectProperties.PropertyType; 23 24 import org.apache.tools.ant.BuildException; 25 import org.apache.tools.ant.Project; 26 import org.apache.tools.ant.Task; 27 import org.apache.tools.ant.taskdefs.ExecTask; 28 import org.apache.tools.ant.types.Path; 29 30 import java.io.File; 31 import java.util.Map; 32 import java.util.Map.Entry; 33 34 /** 35 * Task able to run an Exec task on aapt several times. 36 * It does not follow the exec task format, instead it has its own parameters, which maps 37 * directly to aapt. 38 * 39 */ 40 public final class AaptExecLoopTask extends Task { 41 42 private String mExecutable; 43 private String mCommand; 44 private String mManifest; 45 private String mResources; 46 private String mAssets; 47 private String mAndroidJar; 48 private String mOutFolder; 49 private String mBaseName; 50 51 /** 52 * Sets the value of the "executable" attribute. 53 * @param executable the value. 54 */ setExecutable(String executable)55 public void setExecutable(String executable) { 56 mExecutable = executable; 57 } 58 59 /** 60 * Sets the value of the "command" attribute. 61 * @param command the value. 62 */ setCommand(String command)63 public void setCommand(String command) { 64 mCommand = command; 65 } 66 67 /** 68 * Sets the value of the "manifest" attribute. 69 * @param manifest the value. 70 */ setManifest(Path manifest)71 public void setManifest(Path manifest) { 72 mManifest = manifest.toString(); 73 } 74 75 /** 76 * Sets the value of the "resources" attribute. 77 * @param resources the value. 78 */ setResources(Path resources)79 public void setResources(Path resources) { 80 mResources = resources.toString(); 81 } 82 83 /** 84 * Sets the value of the "assets" attribute. 85 * @param assets the value. 86 */ setAssets(Path assets)87 public void setAssets(Path assets) { 88 mAssets = assets.toString(); 89 } 90 91 /** 92 * Sets the value of the "androidjar" attribute. 93 * @param androidJar the value. 94 */ setAndroidjar(Path androidJar)95 public void setAndroidjar(Path androidJar) { 96 mAndroidJar = androidJar.toString(); 97 } 98 99 /** 100 * Sets the value of the "outfolder" attribute. 101 * @param outFolder the value. 102 */ setOutfolder(Path outFolder)103 public void setOutfolder(Path outFolder) { 104 mOutFolder = outFolder.toString(); 105 } 106 107 /** 108 * Sets the value of the "basename" attribute. 109 * @param baseName the value. 110 */ setBasename(String baseName)111 public void setBasename(String baseName) { 112 mBaseName = baseName; 113 } 114 115 /* 116 * (non-Javadoc) 117 * 118 * Executes the loop. Based on the values inside default.properties, this will 119 * create alternate temporary ap_ files. 120 * 121 * @see org.apache.tools.ant.Task#execute() 122 */ 123 @Override execute()124 public void execute() throws BuildException { 125 Project taskProject = getProject(); 126 127 // first do a full resource package 128 createPackage(null /*configName*/, null /*resourceFilter*/); 129 130 // now see if we need to create file with filtered resources. 131 // Get the project base directory. 132 File baseDir = taskProject.getBaseDir(); 133 ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(), 134 PropertyType.DEFAULT); 135 136 137 ApkSettings apkSettings = ApkConfigurationHelper.getSettings(properties); 138 if (apkSettings != null) { 139 Map<String, String> apkFilters = apkSettings.getResourceFilters(); 140 if (apkFilters.size() > 0) { 141 for (Entry<String, String> entry : apkFilters.entrySet()) { 142 createPackage(entry.getKey(), entry.getValue()); 143 } 144 } 145 } 146 } 147 148 /** 149 * Creates a resource package. 150 * @param configName the name of the filter config. Can be null in which case a full resource 151 * package will be generated. 152 * @param resourceFilter the resource configuration filter to pass to aapt (if configName is 153 * non null) 154 */ createPackage(String configName, String resourceFilter)155 private void createPackage(String configName, String resourceFilter) { 156 Project taskProject = getProject(); 157 158 if (configName == null || resourceFilter == null) { 159 System.out.println("Creating full resource package..."); 160 } else { 161 System.out.println(String.format( 162 "Creating resource package for config '%1$s' (%2$s)...", 163 configName, resourceFilter)); 164 } 165 166 // create a task for the default apk. 167 ExecTask task = new ExecTask(); 168 task.setExecutable(mExecutable); 169 task.setFailonerror(true); 170 171 // aapt command. Only "package" is supported at this time really. 172 task.createArg().setValue(mCommand); 173 174 // filters if needed 175 if (configName != null && resourceFilter != null) { 176 task.createArg().setValue("-c"); 177 task.createArg().setValue(resourceFilter); 178 } 179 180 // force flag 181 task.createArg().setValue("-f"); 182 183 // manifest location 184 task.createArg().setValue("-M"); 185 task.createArg().setValue(mManifest); 186 187 // resources location. This may not exists, and aapt doesn't like it, so we check first. 188 File res = new File(mResources); 189 if (res.isDirectory()) { 190 task.createArg().setValue("-S"); 191 task.createArg().setValue(mResources); 192 } 193 194 // assets location. This may not exists, and aapt doesn't like it, so we check first. 195 File assets = new File(mAssets); 196 if (assets.isDirectory()) { 197 task.createArg().setValue("-A"); 198 task.createArg().setValue(mAssets); 199 } 200 201 // android.jar 202 task.createArg().setValue("-I"); 203 task.createArg().setValue(mAndroidJar); 204 205 // out file. This is based on the outFolder, baseName, and the configName (if applicable) 206 String filename; 207 if (configName != null && resourceFilter != null) { 208 filename = mBaseName + "-" + configName + ".ap_"; 209 } else { 210 filename = mBaseName + ".ap_"; 211 } 212 213 File file = new File(mOutFolder, filename); 214 task.createArg().setValue("-F"); 215 task.createArg().setValue(file.getAbsolutePath()); 216 217 // final setup of the task 218 task.setProject(taskProject); 219 task.setOwningTarget(getOwningTarget()); 220 221 // execute it. 222 task.execute(); 223 } 224 } 225