summaryrefslogtreecommitdiff
path: root/build-system/manifest-merger/src/main/java/com/android/manifmerger/PreValidator.java
diff options
context:
space:
mode:
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.java139
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) {