aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java180
1 files changed, 110 insertions, 70 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java
index 93364a6fd7..be6738fa3b 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidManifestProcessor.java
@@ -57,6 +57,18 @@ import javax.xml.stream.events.XMLEvent;
/** Provides manifest processing oriented tools. */
public class AndroidManifestProcessor {
+
+ /** Wrapper exception for errors thrown during manifest processing. */
+ public static class ManifestProcessingException extends RuntimeException {
+ public ManifestProcessingException(Throwable e) {
+ super(e);
+ }
+
+ public ManifestProcessingException(String message) {
+ super(message);
+ }
+ }
+
private static final ImmutableMap<SystemProperty, String> SYSTEM_PROPERTY_NAMES =
Maps.toMap(
Arrays.asList(SystemProperty.values()),
@@ -109,7 +121,7 @@ public class AndroidManifestProcessor {
* @param logFile The path to write the merger log to.
* @return The path of the resultant manifest, either {@code output}, or {@code manifest} if no
* merging was required.
- * @throws MergeErrorException if a merge error was encountered during merging.
+ * @throws ManifestProcessingException if there was a problem writing the merged manifest.
*/
// TODO(corysmith): Extract manifest processing.
public Path mergeManifest(
@@ -118,7 +130,8 @@ public class AndroidManifestProcessor {
MergeType mergeType,
Map<String, String> values,
Path output,
- Path logFile) throws MergeErrorException {
+ Path logFile)
+ throws ManifestProcessingException {
if (mergeeManifests.isEmpty() && values.isEmpty()) {
return manifest;
}
@@ -141,8 +154,7 @@ public class AndroidManifestProcessor {
placeholders.putAll(values);
for (SystemProperty property : SystemProperty.values()) {
if (values.containsKey(SYSTEM_PROPERTY_NAMES.get(property))) {
- manifestMerger.setOverride(
- property, values.get(SYSTEM_PROPERTY_NAMES.get(property)));
+ manifestMerger.setOverride(property, values.get(SYSTEM_PROPERTY_NAMES.get(property)));
// The manifest merger does not allow explicitly specifying either applicationId or
// packageName as placeholders if SystemProperty.PACKAGE is specified. It forces these
@@ -181,31 +193,19 @@ public class AndroidManifestProcessor {
break;
case ERROR:
mergingReport.log(stdLogger);
- throw new MergeErrorException(mergingReport);
+ throw new ManifestProcessingException(mergingReport.getReportString());
default:
- throw new RuntimeException("Unhandled result type : " + mergingReport.getResult());
+ throw new ManifestProcessingException(
+ "Unhandled result type : " + mergingReport.getResult());
}
- } catch (IOException | MergeFailureException e) {
- throw new RuntimeException(e);
+ } catch (MergeFailureException | IOException e) {
+ throw new ManifestProcessingException(e);
}
return output;
}
- /**
- * Stamp specific properties into the manifest tag of the given manifest.
- *
- * @param variantType The type of rule the manifest belongs to, determining the stamping behavior.
- * @param customPackageForR The package attribute to stamp if not a binary manifest.
- * @param applicationId The package attribute for a binary manifest.
- * @param versionCode The android:versionCode attribute to stamp.
- * @param versionName The android:versionName attribute to stamp.
- * @param primaryData The {@link MergedAndroidData} that contains the manifest to modify.
- * @param processedManifest The path to write the modified manifest.
- * @return A {@link MergedAndroidData} containing the modified manifest, or {@code primaryData} if
- * no modification was required.
- * @throws MergeErrorException if a merge error was encountered during merging.
- */
+ /** Process a manifest for a library or a binary and return the merged android data. */
public MergedAndroidData processManifest(
VariantType variantType,
String customPackageForR,
@@ -214,7 +214,7 @@ public class AndroidManifestProcessor {
String versionName,
MergedAndroidData primaryData,
Path processedManifest)
- throws MergeErrorException {
+ throws IOException {
ManifestMerger2.MergeType mergeType =
variantType == VariantType.DEFAULT
@@ -225,55 +225,91 @@ public class AndroidManifestProcessor {
variantType == VariantType.DEFAULT ? applicationId : customPackageForR;
if (versionCode != -1 || versionName != null || newManifestPackage != null) {
- try {
- Files.createDirectories(processedManifest.getParent());
-
- // The generics on Invoker don't make sense, so ignore them.
- @SuppressWarnings("unchecked")
- Invoker<?> manifestMergerInvoker =
- ManifestMerger2.newMerger(primaryData.getManifest().toFile(), stdLogger, mergeType);
- // Stamp new package
- if (newManifestPackage != null) {
- manifestMergerInvoker.setOverride(SystemProperty.PACKAGE, newManifestPackage);
- }
- // Stamp version and applicationId (if provided) into the manifest
- if (versionCode > 0) {
- manifestMergerInvoker.setOverride(
- SystemProperty.VERSION_CODE, String.valueOf(versionCode));
- }
- if (versionName != null) {
- manifestMergerInvoker.setOverride(SystemProperty.VERSION_NAME, versionName);
- }
-
- MergedManifestKind mergedManifestKind = MergedManifestKind.MERGED;
- if (mergeType == ManifestMerger2.MergeType.APPLICATION) {
- manifestMergerInvoker.withFeatures(Invoker.Feature.REMOVE_TOOLS_DECLARATIONS);
- }
-
- MergingReport mergingReport = manifestMergerInvoker.merge();
- switch (mergingReport.getResult()) {
- case WARNING:
- mergingReport.log(stdLogger);
- writeMergedManifest(mergedManifestKind, mergingReport, processedManifest);
- break;
- case SUCCESS:
- writeMergedManifest(mergedManifestKind, mergingReport, processedManifest);
- break;
- case ERROR:
- mergingReport.log(stdLogger);
- throw new MergeErrorException(mergingReport);
- default:
- throw new RuntimeException("Unhandled result type : " + mergingReport.getResult());
- }
- } catch (IOException | MergeFailureException e) {
- throw new RuntimeException(e);
- }
+ processManifest(
+ versionCode,
+ versionName,
+ primaryData.getManifest(),
+ processedManifest,
+ mergeType,
+ newManifestPackage);
return new MergedAndroidData(
primaryData.getResourceDir(), primaryData.getAssetDir(), processedManifest);
}
return primaryData;
}
+ /** Processes the manifest for a binary and return the manifest Path. */
+ public Path processManifest(
+ String applicationId,
+ int versionCode,
+ String versionName,
+ Path manifest,
+ Path processedManifest) {
+
+ ManifestMerger2.MergeType mergeType = ManifestMerger2.MergeType.APPLICATION;
+
+ String newManifestPackage = applicationId;
+
+ if (versionCode != -1 || versionName != null || newManifestPackage != null) {
+ processManifest(
+ versionCode, versionName, manifest, processedManifest, mergeType, newManifestPackage);
+ return processedManifest;
+ }
+ return manifest;
+ }
+
+ private void processManifest(
+ int versionCode,
+ String versionName,
+ Path primaryManifest,
+ Path processedManifest,
+ MergeType mergeType,
+ String newManifestPackage) {
+ try {
+ Files.createDirectories(processedManifest.getParent());
+
+ // The generics on Invoker don't make sense, so ignore them.
+ @SuppressWarnings("unchecked")
+ Invoker<?> manifestMergerInvoker =
+ ManifestMerger2.newMerger(primaryManifest.toFile(), stdLogger, mergeType);
+ // Stamp new package
+ if (newManifestPackage != null) {
+ manifestMergerInvoker.setOverride(SystemProperty.PACKAGE, newManifestPackage);
+ }
+ // Stamp version and applicationId (if provided) into the manifest
+ if (versionCode > 0) {
+ manifestMergerInvoker.setOverride(SystemProperty.VERSION_CODE, String.valueOf(versionCode));
+ }
+ if (versionName != null) {
+ manifestMergerInvoker.setOverride(SystemProperty.VERSION_NAME, versionName);
+ }
+
+ MergedManifestKind mergedManifestKind = MergedManifestKind.MERGED;
+ if (mergeType == MergeType.APPLICATION) {
+ manifestMergerInvoker.withFeatures(Feature.REMOVE_TOOLS_DECLARATIONS);
+ }
+
+ MergingReport mergingReport = manifestMergerInvoker.merge();
+ switch (mergingReport.getResult()) {
+ case WARNING:
+ mergingReport.log(stdLogger);
+ writeMergedManifest(mergedManifestKind, mergingReport, processedManifest);
+ break;
+ case SUCCESS:
+ writeMergedManifest(mergedManifestKind, mergingReport, processedManifest);
+ break;
+ case ERROR:
+ mergingReport.log(stdLogger);
+ throw new ManifestProcessingException(mergingReport.getReportString());
+ default:
+ throw new ManifestProcessingException(
+ "Unhandled result type : " + mergingReport.getResult());
+ }
+ } catch (IOException | MergeFailureException e) {
+ throw new ManifestProcessingException(e);
+ }
+ }
+
/**
* Overwrite the package attribute of {@code <manifest>} in an AndroidManifest.xml file.
*
@@ -323,18 +359,22 @@ public class AndroidManifestProcessor {
}
writer.flush();
} catch (XMLStreamException | FactoryConfigurationError | IOException e) {
- throw new RuntimeException(e);
+ throw new ManifestProcessingException(e);
}
return output;
}
- private void writeMergedManifest(
+ public void writeMergedManifest(
MergedManifestKind mergedManifestKind, MergingReport mergingReport, Path manifestOut)
- throws IOException {
+ throws ManifestProcessingException {
String manifestContents = mergingReport.getMergedDocument(mergedManifestKind);
String annotatedDocument = mergingReport.getMergedDocument(MergedManifestKind.BLAME);
stdLogger.verbose(annotatedDocument);
- Files.write(manifestOut, manifestContents.getBytes(UTF_8));
+ try {
+ Files.write(manifestOut, manifestContents.getBytes(UTF_8));
+ } catch (IOException e) {
+ throw new ManifestProcessingException(e);
+ }
}
}