All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.manifmerger.ElementsTrimmer Maven / Gradle / Ivy

There is a newer version: 25.3.0
Show newest version
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.manifmerger;

import static com.android.SdkConstants.ANDROID_URI;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.xml.AndroidManifest;

import org.w3c.dom.Attr;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

/**
 * Trims the document from unwanted, repeated elements.
 */
public class ElementsTrimmer {

    /**
     * Trims unwanted, duplicated elements from the merged document.
     * 

* Current trimmed elements are : *

*

    *
  • uses-features with glEsVersion key
  • *
      *
    • The highest 1.x version element will be kept regardless of 'required' flag value
    • *
    • If the above element is present and has a 'false' required flag, there can be at most * one element of a lesser version with 'required' attribute set to true.
    • *
    • The highest 2.x or superior element will be kept regardless of 'required' flag value *
    • *
    • If the above element is present and has a 'false' required flag, there can be at * most one element of a lesser version (but higher than 2.0) with a 'required' attribute * set to true.
    • *
    *
* * @param xmlDocument the xml document to trim. * @param mergingReport the report to log errors and actions. */ public static void trim( @NonNull XmlDocument xmlDocument, @NonNull MergingReport.Builder mergingReport) { // I sort the glEsVersion declaration by value. NavigableMap glEsVersionDeclarations = new TreeMap(); for (XmlElement childElement : xmlDocument.getRootNode().getMergeableElements()) { if (childElement.getType().equals(ManifestModel.NodeTypes.USES_FEATURE)) { Integer value = getGlEsVersion(childElement); if (value != null) { glEsVersionDeclarations.put(value, childElement); } } } // now eliminate all unwanted declarations, revert the sorted map, so we get the // higher elements first. glEsVersionDeclarations = glEsVersionDeclarations.descendingMap(); boolean doneWithAboveTwoTrue = false; boolean doneWithAboveTwoFalse = false; boolean doneWithBelowTwoTrue = false; boolean doneWithBelowTwoFalse = false; for (Map.Entry glEsVersionDeclaration : glEsVersionDeclarations.entrySet()) { boolean removeElement; Attr requiredAttribute = glEsVersionDeclaration.getValue().getXml().getAttributeNodeNS( ANDROID_URI, AndroidManifest.ATTRIBUTE_REQUIRED); boolean isRequired = requiredAttribute == null || Boolean.parseBoolean(requiredAttribute.getValue()); if (glEsVersionDeclaration.getKey() < 0x20000) { // version one. removeElement = (doneWithBelowTwoFalse && doneWithBelowTwoTrue) || (isRequired && doneWithBelowTwoTrue) || (!isRequired && doneWithBelowTwoFalse); if (!removeElement) { doneWithBelowTwoFalse = true; doneWithBelowTwoTrue = isRequired; } } else { // version two or above. removeElement = (doneWithAboveTwoFalse && doneWithAboveTwoTrue) || (isRequired && doneWithAboveTwoTrue) || (!isRequired && doneWithAboveTwoFalse); if (!removeElement) { doneWithAboveTwoFalse = true; doneWithAboveTwoTrue = isRequired; } } if (removeElement) { // if the node only contains glEsVersion, then remove the entire node, // if it also contains android:name, just remove the glEsVersion attribute if (glEsVersionDeclaration.getValue().getXml().getAttributeNodeNS(ANDROID_URI, SdkConstants.ATTR_NAME) != null) { glEsVersionDeclaration.getValue().getXml().removeAttributeNS(ANDROID_URI, AndroidManifest.ATTRIBUTE_GLESVERSION); mergingReport.getActionRecorder().recordAttributeAction( glEsVersionDeclaration.getValue().getAttribute(XmlNode.fromXmlName( "android:" + AndroidManifest.ATTRIBUTE_GLESVERSION)).get(), Actions.ActionType.REJECTED, null /* attributeOperationType */); } else { xmlDocument.getRootNode().getXml().removeChild( glEsVersionDeclaration.getValue().getXml()); mergingReport.getActionRecorder().recordNodeAction( glEsVersionDeclaration.getValue(), Actions.ActionType.REJECTED); } } } } private static Integer getGlEsVersion(XmlElement xmlElement) { Attr glEsVersion = xmlElement.getXml() .getAttributeNodeNS(ANDROID_URI, AndroidManifest.ATTRIBUTE_GLESVERSION); if (glEsVersion == null) { return null; } return getHexValue(glEsVersion); } private static Integer getHexValue(Attr attribute) { return Integer.decode(attribute.getValue()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy