diff options
author | Ryan Mitchell <rtmitchell@google.com> | 2021-05-03 13:46:56 -0700 |
---|---|---|
committer | Ryan Mitchell <rtmitchell@google.com> | 2021-05-03 13:54:55 -0700 |
commit | 1966e1f236926ada5b2a3196b9c07d954ba389d2 (patch) | |
tree | 28b149c4f0ea737f1b3446b5e0edd21eb35e42ce /tools | |
parent | ff68a9adc3454b7cddb2501d8e82bd4b10b2037c (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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/aapt2/dump/DumpManifest.cpp | 21 |
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); |