1 /* 2 * Copyright (C) 2012 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.manifmerger.ManifestMerger; 20 import com.android.sdklib.StdSdkLog; 21 import com.android.sdklib.io.FileOp; 22 23 import org.apache.tools.ant.BuildException; 24 import org.apache.tools.ant.types.Path; 25 26 import java.io.File; 27 import java.io.IOException; 28 import java.util.ArrayList; 29 import java.util.List; 30 31 public class ManifestMergerTask extends SingleDependencyTask { 32 33 private String mAppManifest; 34 private String mOutManifest; 35 36 private ArrayList<Path> mLibraryPaths; 37 private boolean mEnabled = false; 38 setAppManifest(Path appManifest)39 public void setAppManifest(Path appManifest) { 40 mAppManifest = TaskHelper.checkSinglePath("appManifest", appManifest); 41 } 42 setOutManifest(Path outManifest)43 public void setOutManifest(Path outManifest) { 44 mOutManifest = TaskHelper.checkSinglePath("outManifest", outManifest); 45 } 46 setEnabled(boolean enabled)47 public void setEnabled(boolean enabled) { 48 mEnabled = enabled; 49 } 50 51 /** 52 * Returns an object representing a nested <var>library</var> element. 53 */ createLibrary()54 public Object createLibrary() { 55 if (mLibraryPaths == null) { 56 mLibraryPaths = new ArrayList<Path>(); 57 } 58 59 Path path = new Path(getProject()); 60 mLibraryPaths.add(path); 61 62 return path; 63 } 64 65 @Override execute()66 public void execute() throws BuildException { 67 if (mAppManifest == null) { 68 throw new BuildException("Missing attribute appManifest"); 69 } 70 if (mOutManifest == null) { 71 throw new BuildException("Missing attribute outManifest"); 72 } 73 74 // if we merge, then get the rest of the input paths. 75 List<File> libraries = new ArrayList<File>(); 76 if (mLibraryPaths != null) { 77 for (Path pathList : mLibraryPaths) { 78 for (String path : pathList.list()) { 79 libraries.add(new File(path)); 80 } 81 } 82 } 83 84 // prepare input files 85 ArrayList<File> allInputs = new ArrayList<File>(libraries.size() + 1); 86 87 // always: the input manifest. 88 File appManifestFile = new File(mAppManifest); 89 allInputs.add(appManifestFile); 90 91 // if enabled: add the libraries 92 if (mEnabled) { 93 allInputs.addAll(libraries); 94 } 95 96 // figure out the path to the dependency file. 97 String depFile = mOutManifest + ".d"; 98 99 // get InputPath with no extension restrictions 100 List<InputPath> inputPaths = getInputPaths(allInputs, null /*extensionsToCheck*/, 101 null /*factory*/); 102 103 if (initDependencies(depFile, inputPaths) && dependenciesHaveChanged() == false) { 104 System.out.println( 105 "No changes in the AndroidManifest files."); 106 return; 107 } 108 109 System.out.println("Merging AndroidManifest files into one."); 110 111 if (mEnabled == false || libraries.size() == 0) { 112 if (mEnabled == false) { 113 System.out.println("Manifest merger disabled. Using project manifest only."); 114 } else { 115 System.out.println("No libraries. Using project manifest only."); 116 } 117 // no merge (disabled or nothing to merge)? do a simple copy. 118 try { 119 new FileOp().copyFile(appManifestFile, new File(mOutManifest)); 120 } catch (IOException e) { 121 throw new BuildException(e); 122 } 123 } else { 124 System.out.println(String.format("Merging manifests from project and %d libraries.", 125 libraries.size())); 126 ManifestMerger merger = new ManifestMerger(new StdSdkLog()); 127 if (merger.process( 128 new File(mOutManifest), 129 appManifestFile, 130 libraries.toArray(new File[libraries.size()])) == false) { 131 throw new BuildException(); 132 } 133 } 134 135 // generate the dependency file. 136 generateDependencyFile(depFile, inputPaths, mOutManifest); 137 } 138 139 @Override getExecTaskName()140 protected String getExecTaskName() { 141 return "ManifestMerger"; 142 } 143 } 144