summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Mitchell <rtmitchell@google.com>2021-05-03 13:46:56 -0700
committerRyan Mitchell <rtmitchell@google.com>2021-05-03 13:54:55 -0700
commit1966e1f236926ada5b2a3196b9c07d954ba389d2 (patch)
tree28b149c4f0ea737f1b3446b5e0edd21eb35e42ce
parentff68a9adc3454b7cddb2501d8e82bd4b10b2037c (diff)
AAPT2: Only print last uses-sdk tag
When an APK defines multiple "uses-sdk" tags, the Android runtime only uses the minSdkVersion and targetSdkVersion values from the last occurrence of the "uses-sdk" tag. For example an application with the following tags: <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/> <uses-sdk android:maxSdkVersion="28"/> Will have the following version codes at runtime: minSdk=1 targetSdk=1 Another example: <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="28"/> <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="19"/> Will have the following version codes at runtime: minSdk=5 targetSdk=19 AAPT2 must print the version data from only the last tag, skipping other occurrences of the tag. Bug: 175789289 Test: manual Change-Id: If0fece7de1d96046221c89d1b12515bc5c15c301
-rw-r--r--tools/aapt2/dump/DumpManifest.cpp21
1 files changed, 21 insertions, 0 deletions
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);