} else { mergingReportBuilder.getActionRecorder().recordAttributeAction( xmlAttribute, SourcePosition.UNKNOWN,
glEsVersionDeclaration.getValue().getXml().removeAttributeNS(ANDROID_URI, AndroidManifest.ATTRIBUTE_GLESVERSION); mergingReport.getActionRecorder().recordAttributeAction( glEsVersionDeclaration.getValue().getAttribute(XmlNode.fromXmlName( "android:" + AndroidManifest.ATTRIBUTE_GLESVERSION)).get(), xmlDocument.getRootNode().getXml().removeChild( glEsVersionDeclaration.getValue().getXml()); mergingReport.getActionRecorder().recordNodeAction( glEsVersionDeclaration.getValue(), Actions.ActionType.REJECTED);
builder.getActionRecorder().recordDefaultNodeAction(libraryDocument.getRootNode()); performPlaceHolderSubstitution( manifestInfo, libraryDocument, builder, MergeType.LIBRARY);
addIfAbsent(mergingReport.getActionRecorder(), USES_PERMISSION, permission("WRITE_EXTERNAL_STORAGE"), hasWriteToExternalStoragePermission = true; addIfAbsent(mergingReport.getActionRecorder(), USES_PERMISSION, permission("READ_PHONE_STATE"), addIfAbsent(mergingReport.getActionRecorder(), USES_PERMISSION, permission("READ_EXTERNAL_STORAGE"), if (lowerPriorityDocument.getByTypeAndKey( USES_PERMISSION, permission("READ_CONTACTS")).isPresent()) { addIfAbsent(mergingReport.getActionRecorder(), USES_PERMISSION, permission("READ_CALL_LOG"), lowerPriorityDocument.getPackageName() addIfAbsent(mergingReport.getActionRecorder(), USES_PERMISSION, permission("WRITE_CALL_LOG"), lowerPriorityDocument.getPackageName()
mergingReport.getActionRecorder().recordNodeAction(this, Actions.ActionType.REJECTED, lowerPriorityChild);
case MERGE_ONLY_ATTRIBUTES: mergingReport.getActionRecorder().recordNodeAction(higherPriority, Actions.ActionType.MERGED, lowerPriority); mergingReport.getActionRecorder().recordNodeAction(higherPriority, Actions.ActionType.REJECTED, lowerPriority); break;
if (operationType == NodeOperationType.REMOVE || operationType == NodeOperationType.REPLACE) { mergingReport.getActionRecorder().recordNodeAction(thisChild, Actions.ActionType.REJECTED, lowerPriorityChild); break;
report.getActionRecorder().recordAttributeAction( this, Actions.ActionType.REJECTED,
@NonNull XmlAttribute higherPriority) { Actions.AttributeRecord attributeRecord = report.getActionRecorder() .getAttributeCreationRecord(higherPriority);
mergingReport.getActionRecorder().recordNodeAction(thisChildElementOptional.get(), Actions.ActionType.REJECTED, lowerPriorityChild);
mergingReport.getActionRecorder().recordAttributeAction( this, Actions.ActionType.REJECTED, mergingReport.getActionRecorder().recordAttributeAction( this, Actions.ActionType.ADDED,
: new MergingReport.Builder(mergingReportBuilder.getLogger()); builder.getActionRecorder().recordDefaultNodeAction( xmlDocument.getRootNode());
mergingReport.getActionRecorder().recordImplicitRejection(this, implicitNode); return; } else { getXml().setValue(mergedValue); mergingReport.getActionRecorder().recordAttributeAction( this, Actions.ActionType.MERGED,
private Optional<XmlDocument> merge( @NonNull Optional<XmlDocument> xmlDocument, @NonNull LoadedManifestInfo lowerPriorityDocument, @NonNull MergingReport.Builder mergingReportBuilder) throws MergeFailureException { MergingReport.Result validationResult = PreValidator .validate(mergingReportBuilder, lowerPriorityDocument.getXmlDocument()); if (validationResult == MergingReport.Result.ERROR) { mergingReportBuilder.addMessage( lowerPriorityDocument.getXmlDocument().getSourceFile(), MergingReport.Record.Severity.ERROR, "Validation failed, exiting"); return Optional.absent(); } Optional<XmlDocument> result; if (xmlDocument.isPresent()) { result = xmlDocument.get().merge( lowerPriorityDocument.getXmlDocument(), mergingReportBuilder); } else { mergingReportBuilder.getActionRecorder().recordDefaultNodeAction( lowerPriorityDocument.getXmlDocument().getRootNode()); result = Optional.of(lowerPriorityDocument.getXmlDocument()); } // if requested, dump each intermediary merging stage into the report. if (mOptionalFeatures.contains(Invoker.Feature.KEEP_INTERMEDIARY_STAGES) && result.isPresent()) { mergingReportBuilder.addMergingStage(result.get().prettyPrint()); } return result; }
/** * merge this higher priority document with a higher priority document. * @param lowerPriorityDocument the lower priority document to merge in. * @param mergingReportBuilder the merging report to record errors and actions. * @return a new merged {@link com.android.manifmerger.XmlDocument} or * {@link Optional#absent()} if there were errors during the merging activities. */ @NonNull public Optional<XmlDocument> merge( @NonNull XmlDocument lowerPriorityDocument, @NonNull MergingReport.Builder mergingReportBuilder) { if (getFileType() == Type.MAIN) { mergingReportBuilder.getActionRecorder().recordDefaultNodeAction(getRootNode()); } getRootNode().mergeWithLowerPriorityNode( lowerPriorityDocument.getRootNode(), mergingReportBuilder); addImplicitElements(lowerPriorityDocument, mergingReportBuilder); // force re-parsing as new nodes may have appeared. return mergingReportBuilder.hasErrors() ? Optional.<XmlDocument>absent() : Optional.of(reparse()); }
/** * Add an element and its leading comments as the last sub-element of the current element. * @param elementToBeAdded xml element to be added to the current element. * @param mergingReport the merging report to log errors and actions. */ private void addElement( @NonNull XmlElement elementToBeAdded, @NonNull MergingReport.Builder mergingReport) { List<Node> comments = getLeadingComments(elementToBeAdded.getXml()); // record all the actions before the node is moved from the library document to the main // merged document. mergingReport.getActionRecorder().recordDefaultNodeAction(elementToBeAdded); // only in the new file, just import it. Node node = getXml().getOwnerDocument().adoptNode(elementToBeAdded.getXml()); getXml().appendChild(node); // also adopt the child's comments if any. for (Node comment : comments) { Node newComment = getXml().getOwnerDocument().adoptNode(comment); getXml().insertBefore(newComment, node); } mergingReport.getLogger().verbose("Adopted " + node); }
/** * Post validation of the merged document. This will essentially check that all merging * instructions were applied at least once. * * @param xmlDocument merged document to check. * @param mergingReport report for errors and warnings. */ public static void validate( @NonNull XmlDocument xmlDocument, @NonNull MergingReport.Builder mergingReport) { Preconditions.checkNotNull(xmlDocument); Preconditions.checkNotNull(mergingReport); enforceAndroidNamespaceDeclaration(xmlDocument); reOrderElements(xmlDocument.getRootNode()); validate(xmlDocument.getRootNode(), mergingReport.getActionRecorder().build(), mergingReport); }
/** * Perform {@link ManifestSystemProperty} injection. * @param mergingReport to log actions and errors. * @param xmlDocument the xml document to inject into. */ protected void performSystemPropertiesInjection( @NonNull MergingReport.Builder mergingReport, @NonNull XmlDocument xmlDocument) { for (ManifestSystemProperty manifestSystemProperty : ManifestSystemProperty.values()) { String propertyOverride = mSystemPropertyResolver.getValue(manifestSystemProperty); if (propertyOverride != null) { manifestSystemProperty.addTo( mergingReport.getActionRecorder(), xmlDocument, propertyOverride); } } }