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
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index f29c918..61ba09b 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -132,6 +132,12 @@
     /** 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 @@
   // 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);