AAPT2: Implement attribute compat versioning
This change defines some hardcoded rules to degrade
attributes in newer SDKs to specific older attributes.
An attribute with a degrade rule will generate a new XML for the API
in which the attribute resulting from the degradation was introduced.
Since API 22 (Lollipop MR1), attributes are correctly ignored and do
not need to be versioned. In XML files defined for APIs 22+, the
original and degraded attributes coexist in the same XML file.
One such example is paddingHorizontal, introduced in API 26.
paddingHorizontal degrades to paddingLeft and paddingRight, which
were both introduced in API 1.
Bug: 35763493
Test: make aapt2_tests
Change-Id: I4aa8755a9ee2c0cc5afdc55c3d30093fd3a47f3d
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index 6950c30..2dc99d6 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -35,6 +35,8 @@
class RawVisitor;
+class Element;
+
/**
* Base class for all XML nodes.
*/
@@ -51,7 +53,11 @@
void AppendChild(std::unique_ptr<Node> child);
void InsertChild(size_t index, std::unique_ptr<Node> child);
virtual void Accept(RawVisitor* visitor) = 0;
- virtual std::unique_ptr<Node> Clone() = 0;
+
+ using ElementCloneFunc = std::function<void(const Element&, Element*)>;
+
+ // Clones the Node subtree, using the given function to decide how to clone an Element.
+ virtual std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) = 0;
};
/**
@@ -72,12 +78,16 @@
std::string namespace_prefix;
std::string namespace_uri;
- std::unique_ptr<Node> Clone() override;
+ std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) override;
};
struct AaptAttribute {
- Maybe<ResourceId> id;
+ explicit AaptAttribute(const ::aapt::Attribute& attr, const Maybe<ResourceId>& resid = {})
+ : attribute(attr), id(resid) {
+ }
+
aapt::Attribute attribute;
+ Maybe<ResourceId> id;
};
/**
@@ -102,6 +112,8 @@
std::vector<Attribute> attributes;
Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name);
+ const Attribute* FindAttribute(const android::StringPiece& ns,
+ const android::StringPiece& name) const;
xml::Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name);
xml::Element* FindChildWithAttribute(const android::StringPiece& ns,
const android::StringPiece& name,
@@ -109,7 +121,7 @@
const android::StringPiece& attr_name,
const android::StringPiece& attr_value);
std::vector<xml::Element*> GetChildElements();
- std::unique_ptr<Node> Clone() override;
+ std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) override;
};
/**
@@ -119,7 +131,7 @@
public:
std::string text;
- std::unique_ptr<Node> Clone() override;
+ std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) override;
};
/**