diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/aapt/Android.bp | 3 | ||||
-rw-r--r-- | tools/aapt/Command.cpp | 55 | ||||
-rw-r--r-- | tools/aapt2/dump/DumpManifest.cpp | 21 |
3 files changed, 79 insertions, 0 deletions
diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp index c75ba71c4432..a19d183d617b 100644 --- a/tools/aapt/Android.bp +++ b/tools/aapt/Android.bp @@ -124,6 +124,9 @@ cc_binary_host { srcs: ["Main.cpp"], use_version_lib: true, static_libs: ["libaapt"], + dist: { + targets: ["aapt2_artifacts"], + }, } // ========================================================== diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 21386b88ce2c..f2c3b86e409e 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -969,6 +969,8 @@ int doDump(Bundle* bundle) densities.add(dens); } + std::vector<ResXMLParser::ResXMLPosition> tagsToSkip; + size_t len; ResXMLTree::event_code_t code; int depth = 0; @@ -1091,6 +1093,42 @@ int doDump(Bundle* bundle) Vector<FeatureGroup> featureGroups; KeyedVector<String8, ImpliedFeature> impliedFeatures; + { + int curDepth = 0; + ResXMLParser::ResXMLPosition initialPos; + tree.getPosition(&initialPos); + + // Find all of the "uses-sdk" tags within the "manifest" tag. + std::vector<ResXMLParser::ResXMLPosition> usesSdkTagPositions; + ResXMLParser::ResXMLPosition curPos; + while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && + code != ResXMLTree::BAD_DOCUMENT) { + if (code == ResXMLTree::END_TAG) { + curDepth--; + continue; + } + if (code == ResXMLTree::START_TAG) { + curDepth++; + } + const char16_t* ctag16 = tree.getElementName(&len); + if (ctag16 == NULL || String8(ctag16) != "uses-sdk" || curDepth != 2) { + continue; + } + + tree.getPosition(&curPos); + usesSdkTagPositions.emplace_back(curPos); + } + + // Skip all "uses-sdk" tags besides the very last tag. The android runtime only uses + // the attribute values from the last defined tag. + for (size_t i = 0; i < usesSdkTagPositions.size() - 1; i++) { + tagsToSkip.emplace_back(usesSdkTagPositions[i]); + } + + // Reset the position before parsing. + tree.setPosition(initialPos); + } + while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { @@ -1202,8 +1240,25 @@ int doDump(Bundle* bundle) if (code != ResXMLTree::START_TAG) { continue; } + depth++; + // If this tag should be skipped, skip to the end of this tag. + ResXMLParser::ResXMLPosition curPos; + tree.getPosition(&curPos); + if (std::find(tagsToSkip.begin(), tagsToSkip.end(), curPos) != tagsToSkip.end()) { + const int breakDepth = depth - 1; + while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && + code != ResXMLTree::BAD_DOCUMENT) { + if (code == ResXMLTree::END_TAG && --depth == breakDepth) { + break; + } else if (code == ResXMLTree::START_TAG) { + depth++; + } + } + continue; + } + const char16_t* ctag16 = tree.getElementName(&len); if (ctag16 == NULL) { SourcePos(manifestFile, tree.getLineNumber()).error( diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index f29c9185cafa..61ba09b6a3c9 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -132,6 +132,12 @@ class ManifestExtractor { /** Adds an element to the list of children of the element. */ void AddChild(std::unique_ptr<Element>& child) { children_.push_back(std::move(child)); } + template <typename Predicate> + void Filter(Predicate&& func) { + children_.erase(std::remove_if(children_.begin(), children_.end(), + [&](const auto& e) { return func(e.get()); })); + } + /** Retrieves the list of children of the element. */ const std::vector<std::unique_ptr<Element>>& children() const { return children_; @@ -1963,6 +1969,21 @@ bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) { // Extract badging information auto root = Visit(element); + // Filter out all "uses-sdk" tags besides the very last tag. The android runtime only uses the + // attribute values from the last defined tag. + std::vector<UsesSdkBadging*> filtered_uses_sdk_tags; + for (const auto& child : root->children()) { + if (auto uses_sdk = ElementCast<UsesSdkBadging>(child.get())) { + filtered_uses_sdk_tags.emplace_back(uses_sdk); + } + } + filtered_uses_sdk_tags.pop_back(); + + root->Filter([&](const ManifestExtractor::Element* e) { + return std::find(filtered_uses_sdk_tags.begin(), filtered_uses_sdk_tags.end(), e) != + filtered_uses_sdk_tags.end(); + }); + // Print the elements in order seen Print(root.get(), printer); |