diff options
Diffstat (limited to 'build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java')
-rw-r--r-- | build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java | 139 |
1 files changed, 89 insertions, 50 deletions
diff --git a/build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java b/build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java index accde08634..9f24340bce 100644 --- a/build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java +++ b/build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java @@ -18,7 +18,6 @@ package com.android.manifmerger; import static com.android.SdkConstants.ANDROID_URI; import static com.android.manifmerger.ManifestMerger2.COMPATIBLE_SCREENS_SUB_MANIFEST; -import static com.android.manifmerger.ManifestMerger2.MergeType.APPLICATION; import static com.android.manifmerger.ManifestMerger2.WEAR_APP_SUB_MANIFEST; import static com.android.manifmerger.MergingReport.Record.Severity.ERROR; import static com.android.manifmerger.MergingReport.Record.Severity.WARNING; @@ -26,6 +25,7 @@ import static com.android.manifmerger.XmlNode.NodeKey; import com.android.SdkConstants; import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.xml.AndroidManifest; import com.google.common.base.Joiner; import com.google.common.base.Strings; @@ -69,22 +69,28 @@ public class PreValidator { * * @param mergingReport report to log warnings and errors. * @param xmlDocument the loaded xml part. - * @param mergeType the merge type. - * @param validateExtractNativeLibsAttribute whether to validate the application element's - * {@link SdkConstants#ATTR_EXTRACT_NATIVE_LIBS} attribute + * @param validateExtractNativeLibsFromSources whether to warn if the {@link + * SdkConstants#ATTR_EXTRACT_NATIVE_LIBS} attribute is set in a source (MAIN or OVERLAY) + * manifest. + * @param validateExtractNativeLibsFromDependencies whether to warn if the {@link + * SdkConstants#ATTR_EXTRACT_NATIVE_LIBS} attribute is set to true in a dependency (LIBRARY) + * manifest. * @return one the {@link MergingReport.Result} value. */ @NonNull public static MergingReport.Result validate( @NonNull MergingReport.Builder mergingReport, @NonNull XmlDocument xmlDocument, - @NonNull ManifestMerger2.MergeType mergeType, - boolean validateExtractNativeLibsAttribute) { + boolean validateExtractNativeLibsFromSources, + boolean validateExtractNativeLibsFromDependencies) { validatePackageAttribute( mergingReport, xmlDocument.getRootNode(), xmlDocument.getFileType()); - if (validateExtractNativeLibsAttribute) { - validateExtractNativeLibsAttribute(mergingReport, xmlDocument, mergeType); + if (validateExtractNativeLibsFromSources) { + validateExtractNativeLibsFromSources(mergingReport, xmlDocument); + } + if (validateExtractNativeLibsFromDependencies) { + validateExtractNativeLibsFromDependencies(mergingReport, xmlDocument); } return validate(mergingReport, xmlDocument.getRootNode()); } @@ -192,55 +198,88 @@ public class PreValidator { } } - /** Warn if android:extractNativeLibs is set in the MAIN or OVERLAY manifests. */ - private static void validateExtractNativeLibsAttribute( - @NonNull MergingReport.Builder mergingReport, - @NonNull XmlDocument xmlDocument, - @NonNull ManifestMerger2.MergeType mergeType) { - // Don't warn for manifests coming from dependencies because there is no simple fix. + /** Warn if android:extractNativeLibs is set in a MAIN or OVERLAY manifest. */ + private static void validateExtractNativeLibsFromSources( + @NonNull MergingReport.Builder mergingReport, @NonNull XmlDocument xmlDocument) { + // Ignore manifests coming from dependencies. if (xmlDocument.getFileType() == XmlDocument.Type.LIBRARY) { return; } - Optional<XmlElement> applicationElement = - xmlDocument.getByTypeAndKey(ManifestModel.NodeTypes.APPLICATION, null); - applicationElement.ifPresent( - element -> { - maybeWarnAboutAttribute( - mergingReport, - element, + final Boolean extractNativeLibsValue = getExtractNativeLibsValue(xmlDocument); + if (extractNativeLibsValue != null) { + String warning = + String.format( + "android:%1$s should not be specified in this " + + "source AndroidManifest.xml file. See " + + "%2$s for more information.\n" + + "The AGP Upgrade Assistant can remove " + + "the attribute from the " + + "AndroidManifest.xml file and update the " + + "build file accordingly. See %3$s for " + + "more information.", SdkConstants.ATTR_EXTRACT_NATIVE_LIBS, "https://d.android.com/guide/topics/manifest/application-element#extractNativeLibs", - mergeType); - }); + "https://d.android.com/studio/build/agp-upgrade-assistant"); + getExtractNativeLibsAttribute(xmlDocument) + .ifPresent(it -> mergingReport.addMessage(it, WARNING, warning)); + } } - private static void maybeWarnAboutAttribute( - @NonNull MergingReport.Builder mergingReport, - @NonNull XmlElement xmlElement, - @NonNull String attributeLocalName, - @NonNull String link, - @NonNull ManifestMerger2.MergeType mergeType) { - Optional<XmlAttribute> xmlAttribute = - xmlElement.getAttribute( - XmlNode.fromNSName(ANDROID_URI, "android", attributeLocalName)); - xmlAttribute.ifPresent( - it -> { - String warning = - String.format( - "android:%1$s should not be specified in source " - + "AndroidManifest.xml files. See %2$s for more " - + "information.", - attributeLocalName, link); - if (mergeType == APPLICATION) { - warning += - " The AGP Upgrade Assistant can remove the attribute " - + "from the AndroidManifest.xml file and " - + "update the build file accordingly. See " - + "https://d.android.com/studio/build/agp-upgrade-assistant " - + "for more information."; - } - mergingReport.addMessage(it, WARNING, warning); - }); + /** Warn if android:extractNativeLibs is set to true in LIBRARY manifest. */ + private static void validateExtractNativeLibsFromDependencies( + @NonNull MergingReport.Builder mergingReport, @NonNull XmlDocument xmlDocument) { + // Ignore MAIN and OVERLAY manifests. + if (xmlDocument.getFileType() != XmlDocument.Type.LIBRARY) { + return; + } + final Boolean extractNativeLibsValue = getExtractNativeLibsValue(xmlDocument); + if (Boolean.TRUE.equals(extractNativeLibsValue)) { + String warning = + String.format( + "android:%1$s is set to true in a dependency's " + + "AndroidManifest.xml, but not in the " + + "app's merged manifest. If the " + + "dependency truly requires its native " + + "libraries to be extracted, the app can " + + "be configured to do so by setting the " + + "jniLibs.useLegacyPackaging DSL to " + + "true.\n" + + "Otherwise, you can silence this type of " + + "warning by adding %2$s=true to your " + + "gradle.properties file.", + SdkConstants.ATTR_EXTRACT_NATIVE_LIBS, + "android.experimental.suppressExtractNativeLibsWarnings"); + getExtractNativeLibsAttribute(xmlDocument) + .ifPresent(it -> mergingReport.addMessage(it, WARNING, warning)); + } + } + + /** + * @param xmlDocument the XmlDocument to check for the value of the android:extractNativeLibs + * attribute + * @return the Boolean value of the android:extractNativeLibs attribute, or null if it's not set + */ + @Nullable + static Boolean getExtractNativeLibsValue(XmlDocument xmlDocument) { + final XmlAttribute extractNativeLibsAttribute = + getExtractNativeLibsAttribute(xmlDocument).orElse(null); + if (extractNativeLibsAttribute == null) { + return null; + } + return Boolean.valueOf(extractNativeLibsAttribute.getValue()); + } + + private static Optional<XmlAttribute> getExtractNativeLibsAttribute(XmlDocument xmlDocument) { + if (xmlDocument == null) { + return Optional.empty(); + } + final XmlElement applicationElement = + xmlDocument.getByTypeAndKey(ManifestModel.NodeTypes.APPLICATION, null).orElse(null); + if (applicationElement == null) { + return Optional.empty(); + } + return applicationElement.getAttribute( + XmlNode.fromNSName(ANDROID_URI, "android", SdkConstants.ATTR_EXTRACT_NATIVE_LIBS)); } private static boolean isSubManifest(@NonNull XmlElement manifest) { |