diff options
| author | 2022-12-08 18:07:58 +0000 | |
|---|---|---|
| committer | 2022-12-13 15:19:08 +0000 | |
| commit | 32c0c03783e7d3fe27b62569ab70904e249ffa5e (patch) | |
| tree | 2241d1e5caee037a51498d68f6a8f3faed78e302 | |
| parent | e778a656fc0ed848056b9de12a0539734f13ce6e (diff) | |
Allow to use 'aapt2 dump' to analyze APKs generated by aapt/custom tools.
This CL fixes four compatibility issues:
* verifies xml element is placed under valid parent tag inside Inflate;
* FindElement searches an element in a reverse order, this is
because aapt processes tags one-by-one and always takes the latest.
* allows to resolve string from StyledString resource type;
* bug that prevents 'payment' component to be detected.
At the momemnt aapt2 dump does not work correctly for APKs where xml
elements are placed in wrong place (For example if '<uses-permission>'
is declared under '<application>', aapt2 will still report it).
This is essential for Play migration from aapt to aapt2 because not
all our APKs are generated by aapt2 and might contain wrongly placed
elements.
CL is verified on our full APK database and confirmed to fix all issues.
Bug: b/260704482
Test: Dump_test, manual run on Play's DB of APKs
Change-Id: I0b10ecc15a712fd13674a239f91157aba58fa620
| -rw-r--r-- | tools/aapt2/cmd/Dump_test.cpp | 17 | ||||
| -rw-r--r-- | tools/aapt2/dump/DumpManifest.cpp | 279 | ||||
| -rw-r--r-- | tools/aapt2/integration-tests/DumpTest/built_with_aapt.apk | bin | 0 -> 930 bytes | |||
| -rw-r--r-- | tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt | 11 | ||||
| -rw-r--r-- | tools/aapt2/integration-tests/DumpTest/components_expected.txt | 1 | ||||
| -rw-r--r-- | tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt | 1 | ||||
| -rw-r--r-- | tools/aapt2/integration-tests/DumpTest/components_full_proto.txt | 1 |
7 files changed, 194 insertions, 116 deletions
diff --git a/tools/aapt2/cmd/Dump_test.cpp b/tools/aapt2/cmd/Dump_test.cpp index b1c69cd9a7b7..df35ebbc064d 100644 --- a/tools/aapt2/cmd/Dump_test.cpp +++ b/tools/aapt2/cmd/Dump_test.cpp @@ -108,4 +108,21 @@ TEST_F(DumpTest, DumpBadgingPermissionsOnly) { ASSERT_EQ(output, expected); } +TEST_F(DumpTest, DumpBadgingApkBuiltWithAaptAndTagsInWrongPlace) { + auto apk_path = file::BuildPath({android::base::GetExecutableDirectory(), "integration-tests", + "DumpTest", "built_with_aapt.apk"}); + auto loaded_apk = LoadedApk::LoadApkFromPath(apk_path, &noop_diag); + + std::string output; + DumpBadgingToString(loaded_apk.get(), &output, /* include_meta_data= */ false, + /* only_permissions= */ false); + + std::string expected; + auto expected_path = + file::BuildPath({android::base::GetExecutableDirectory(), "integration-tests", "DumpTest", + "built_with_aapt_expected.txt"}); + ::android::base::ReadFileToString(expected_path, &expected); + ASSERT_EQ(output, expected); +} + } // namespace aapt diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index d60869af2846..5a46a6691b6c 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -223,7 +223,8 @@ class ManifestExtractor { Element() = default; virtual ~Element() = default; - static std::unique_ptr<Element> Inflate(ManifestExtractor* extractor, xml::Element* el); + static std::unique_ptr<Element> Inflate(ManifestExtractor* extractor, xml::Element* el, + const std::string& parent_tag); /** Writes out the extracted contents of the element. */ virtual void Print(text::Printer* printer) { @@ -249,10 +250,15 @@ class ManifestExtractor { } /** Retrieves the extracted xml element tag. */ - const std::string tag() const { + const std::string& tag() const { return tag_; } + /** Whether this element has special Extract/Print/ToProto logic. */ + bool is_featured() const { + return featured_; + } + protected: ManifestExtractor* extractor() const { return extractor_; @@ -394,6 +400,8 @@ class ManifestExtractor { return &(*intValue->value); } else if (RawString* rawValue = ValueCast<RawString>(value)) { return &(*rawValue->value); + } else if (StyledString* styledStrValue = ValueCast<StyledString>(value)) { + return &(styledStrValue->value->value); } else if (FileReference* strValue = ValueCast<FileReference>(value)) { return &(*strValue->path); } @@ -424,6 +432,7 @@ class ManifestExtractor { ManifestExtractor* extractor_; std::vector<std::unique_ptr<Element>> children_; std::string tag_; + bool featured_ = false; }; friend Element; @@ -446,7 +455,7 @@ class ManifestExtractor { bool DumpProto(pb::Badging* out_badging); /** Recursively visit the xml element tree and return a processed badging element tree. */ - std::unique_ptr<Element> Visit(xml::Element* element); + std::unique_ptr<Element> Visit(xml::Element* element, const std::string& parent_tag); /** Resets target SDK to 0. */ void ResetTargetSdk() { @@ -485,7 +494,7 @@ class ManifestExtractor { } /** Retrieves the current stack of parent during data extraction. */ - const std::vector<Element*> parent_stack() const { + const std::vector<Element*>& parent_stack() const { return parent_stack_; } @@ -533,8 +542,9 @@ static ManifestExtractor::Element* FindElement(ManifestExtractor::Element* root, if (f(root)) { return root; } - for (auto& child : root->children()) { - if (auto b2 = FindElement(child.get(), f)) { + const auto& children = root->children(); + for (auto it = children.rbegin(); it != children.rend(); ++it) { + if (auto b2 = FindElement(it->get(), f)) { return b2; } } @@ -1348,11 +1358,6 @@ class UsesPermission : public ManifestExtractor::Element { std::string impliedReason; void Extract(xml::Element* element) override { - const auto parent_stack = extractor()->parent_stack(); - if (!extractor()->options_.only_permissions && - (parent_stack.size() != 1 || !ElementCast<Manifest>(parent_stack[0]))) { - return; - } name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); std::string feature = GetAttributeStringDefault(FindAttribute(element, REQUIRED_FEATURE_ATTR), ""); @@ -1477,11 +1482,6 @@ class UsesPermissionSdk23 : public ManifestExtractor::Element { const int32_t* maxSdkVersion = nullptr; void Extract(xml::Element* element) override { - const auto parent_stack = extractor()->parent_stack(); - if (!extractor()->options_.only_permissions && - (parent_stack.size() != 1 || !ElementCast<Manifest>(parent_stack[0]))) { - return; - } name = GetAttributeString(FindAttribute(element, NAME_ATTR)); maxSdkVersion = GetAttributeInteger(FindAttribute(element, MAX_SDK_VERSION_ATTR)); @@ -1717,11 +1717,8 @@ class UsesLibrary : public ManifestExtractor::Element { int required; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); - required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1); - } + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1); } void Print(text::Printer* printer) override { @@ -1749,12 +1746,9 @@ class StaticLibrary : public ManifestExtractor::Element { int versionMajor; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); - version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0); - versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); - } + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); } void Print(text::Printer* printer) override { @@ -1781,13 +1775,10 @@ class UsesStaticLibrary : public ManifestExtractor::Element { std::vector<std::string> certDigests; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); - version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0); - versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); - AddCertDigest(element); - } + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); + AddCertDigest(element); } void AddCertDigest(xml::Element* element) { @@ -1829,11 +1820,8 @@ class SdkLibrary : public ManifestExtractor::Element { int versionMajor; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); - versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); - } + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); } void Print(text::Printer* printer) override { @@ -1857,12 +1845,9 @@ class UsesSdkLibrary : public ManifestExtractor::Element { std::vector<std::string> certDigests; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); - versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); - AddCertDigest(element); - } + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); + AddCertDigest(element); } void AddCertDigest(xml::Element* element) { @@ -1902,11 +1887,8 @@ class UsesNativeLibrary : public ManifestExtractor::Element { int required; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); - required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1); - } + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1); } void Print(text::Printer* printer) override { @@ -2251,14 +2233,11 @@ class UsesPackage : public ManifestExtractor::Element { std::vector<std::string> certDigests; void Extract(xml::Element* element) override { - auto parent_stack = extractor()->parent_stack(); - if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { - packageType = GetAttributeString(FindAttribute(element, PACKAGE_TYPE_ATTR)); - name = GetAttributeString(FindAttribute(element, NAME_ATTR)); - version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0); - versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); - AddCertDigest(element); - } + packageType = GetAttributeString(FindAttribute(element, PACKAGE_TYPE_ATTR)); + name = GetAttributeString(FindAttribute(element, NAME_ATTR)); + version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); + AddCertDigest(element); } void AddCertDigest(xml::Element* element) { @@ -2480,7 +2459,7 @@ bool ManifestExtractor::Extract(android::IDiagnostics* diag) { // Print only the <uses-permission>, <uses-permission-sdk23>, and <permission> elements if // printing only permission elements is requested if (options_.only_permissions) { - root_element_ = ManifestExtractor::Element::Inflate(this, element); + root_element_ = ManifestExtractor::Element::Inflate(this, element, ""); if (auto manifest = ElementCast<Manifest>(root_element_.get())) { manifest->only_package_name = true; @@ -2489,7 +2468,7 @@ bool ManifestExtractor::Extract(android::IDiagnostics* diag) { if (child->name == "uses-permission" || child->name == "uses-permission-sdk-23" || child->name == "permission") { // Inflate the element and its descendants - auto permission_element = Visit(child); + auto permission_element = Visit(child, "manifest"); manifest->AddChild(permission_element); } } @@ -2528,7 +2507,7 @@ bool ManifestExtractor::Extract(android::IDiagnostics* diag) { } // Extract badging information - root_element_ = Visit(element); + root_element_ = 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. @@ -2683,7 +2662,7 @@ bool ManifestExtractor::Extract(android::IDiagnostics* diag) { (meta_data->name == "android.nfc.cardemulation.off_host_apdu_service" && offhost_apdu_action)) { // Attempt to load the resource file - if (!meta_data->resource.empty()) { + if (meta_data->resource.empty()) { return; } auto resource = this->apk_->LoadXml(meta_data->resource, diag); @@ -2878,58 +2857,66 @@ bool ManifestExtractor::DumpProto(pb::Badging* out_badging) { return true; } +template <typename T> +constexpr const char* GetExpectedTagForType() { + // This array does not appear at runtime, as GetExpectedTagForType function is used by compiler + // to inject proper 'expected_tag' into ElementCast. + std::array<std::pair<const char*, bool>, 37> tags = { + std::make_pair("action", std::is_same<Action, T>::value), + std::make_pair("activity", std::is_same<Activity, T>::value), + std::make_pair("additional-certificate", std::is_same<AdditionalCertificate, T>::value), + std::make_pair("application", std::is_same<Application, T>::value), + std::make_pair("category", std::is_same<Category, T>::value), + std::make_pair("compatible-screens", std::is_same<CompatibleScreens, T>::value), + std::make_pair("feature-group", std::is_same<FeatureGroup, T>::value), + std::make_pair("input-type", std::is_same<InputType, T>::value), + std::make_pair("intent-filter", std::is_same<IntentFilter, T>::value), + std::make_pair("meta-data", std::is_same<MetaData, T>::value), + std::make_pair("manifest", std::is_same<Manifest, T>::value), + std::make_pair("original-package", std::is_same<OriginalPackage, T>::value), + std::make_pair("overlay", std::is_same<Overlay, T>::value), + std::make_pair("package-verifier", std::is_same<PackageVerifier, T>::value), + std::make_pair("permission", std::is_same<Permission, T>::value), + std::make_pair("property", std::is_same<Property, T>::value), + std::make_pair("provider", std::is_same<Provider, T>::value), + std::make_pair("receiver", std::is_same<Receiver, T>::value), + std::make_pair("required-feature", std::is_same<RequiredFeature, T>::value), + std::make_pair("required-not-feature", std::is_same<RequiredNotFeature, T>::value), + std::make_pair("screen", std::is_same<Screen, T>::value), + std::make_pair("service", std::is_same<Service, T>::value), + std::make_pair("sdk-library", std::is_same<SdkLibrary, T>::value), + std::make_pair("static-library", std::is_same<StaticLibrary, T>::value), + std::make_pair("supports-gl-texture", std::is_same<SupportsGlTexture, T>::value), + std::make_pair("supports-input", std::is_same<SupportsInput, T>::value), + std::make_pair("supports-screens", std::is_same<SupportsScreen, T>::value), + std::make_pair("uses-configuration", std::is_same<UsesConfiguarion, T>::value), + std::make_pair("uses-feature", std::is_same<UsesFeature, T>::value), + std::make_pair("uses-library", std::is_same<UsesLibrary, T>::value), + std::make_pair("uses-native-library", std::is_same<UsesNativeLibrary, T>::value), + std::make_pair("uses-package", std::is_same<UsesPackage, T>::value), + std::make_pair("uses-permission", std::is_same<UsesPermission, T>::value), + std::make_pair("uses-permission-sdk-23", std::is_same<UsesPermissionSdk23, T>::value), + std::make_pair("uses-sdk", std::is_same<UsesSdkBadging, T>::value), + std::make_pair("uses-sdk-library", std::is_same<UsesSdkLibrary, T>::value), + std::make_pair("uses-static-library", std::is_same<UsesStaticLibrary, T>::value), + }; + for (const auto& pair : tags) { + if (pair.second) { + return pair.first; + } + } + return nullptr; +} + /** * Returns the element casted to the type if the element is of that type. Otherwise, returns a null * pointer. **/ template<typename T> T* ElementCast(ManifestExtractor::Element* element) { - if (element == nullptr) { - return nullptr; - } - - const std::unordered_map<std::string, bool> kTagCheck = { - {"action", std::is_base_of<Action, T>::value}, - {"activity", std::is_base_of<Activity, T>::value}, - {"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value}, - {"application", std::is_base_of<Application, T>::value}, - {"category", std::is_base_of<Category, T>::value}, - {"compatible-screens", std::is_base_of<CompatibleScreens, T>::value}, - {"feature-group", std::is_base_of<FeatureGroup, T>::value}, - {"input-type", std::is_base_of<InputType, T>::value}, - {"intent-filter", std::is_base_of<IntentFilter, T>::value}, - {"meta-data", std::is_base_of<MetaData, T>::value}, - {"manifest", std::is_base_of<Manifest, T>::value}, - {"original-package", std::is_base_of<OriginalPackage, T>::value}, - {"overlay", std::is_base_of<Overlay, T>::value}, - {"package-verifier", std::is_base_of<PackageVerifier, T>::value}, - {"permission", std::is_base_of<Permission, T>::value}, - {"property", std::is_base_of<Property, T>::value}, - {"provider", std::is_base_of<Provider, T>::value}, - {"receiver", std::is_base_of<Receiver, T>::value}, - {"required-feature", std::is_base_of<RequiredFeature, T>::value}, - {"required-not-feature", std::is_base_of<RequiredNotFeature, T>::value}, - {"screen", std::is_base_of<Screen, T>::value}, - {"service", std::is_base_of<Service, T>::value}, - {"sdk-library", std::is_base_of<SdkLibrary, T>::value}, - {"static-library", std::is_base_of<StaticLibrary, T>::value}, - {"supports-gl-texture", std::is_base_of<SupportsGlTexture, T>::value}, - {"supports-input", std::is_base_of<SupportsInput, T>::value}, - {"supports-screens", std::is_base_of<SupportsScreen, T>::value}, - {"uses-configuration", std::is_base_of<UsesConfiguarion, T>::value}, - {"uses-feature", std::is_base_of<UsesFeature, T>::value}, - {"uses-library", std::is_base_of<UsesLibrary, T>::value}, - {"uses-native-library", std::is_base_of<UsesNativeLibrary, T>::value}, - {"uses-package", std::is_base_of<UsesPackage, T>::value}, - {"uses-permission", std::is_base_of<UsesPermission, T>::value}, - {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value}, - {"uses-sdk", std::is_base_of<UsesSdkBadging, T>::value}, - {"uses-sdk-library", std::is_base_of<UsesSdkLibrary, T>::value}, - {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value}, - }; - - auto check = kTagCheck.find(element->tag()); - if (check != kTagCheck.end() && check->second) { + constexpr const char* expected_tag = GetExpectedTagForType<T>(); + if (element != nullptr && expected_tag != nullptr && element->is_featured() && + element->tag() == expected_tag) { return static_cast<T*>(element); } return nullptr; @@ -2941,9 +2928,9 @@ std::unique_ptr<T> CreateType() { } std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( - ManifestExtractor* extractor, xml::Element* el) { - const std::unordered_map<std::string, - std::function<std::unique_ptr<ManifestExtractor::Element>()>> + ManifestExtractor* extractor, xml::Element* el, const std::string& parent_tag) { + static const std::unordered_map<std::string_view, + std::function<std::unique_ptr<ManifestExtractor::Element>()>> kTagCheck = { {"action", &CreateType<Action>}, {"activity", &CreateType<Activity>}, @@ -2983,12 +2970,71 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( {"uses-sdk-library", &CreateType<UsesSdkLibrary>}, {"uses-static-library", &CreateType<UsesStaticLibrary>}, }; - + static constexpr std::array<std::pair<std::string_view, std::string_view>, 53> + kValidChildParentTags = { + std::make_pair("action", "intent-filter"), + std::make_pair("activity", "application"), + std::make_pair("additional-certificate", "uses-package"), + std::make_pair("additional-certificate", "uses-static-library"), + std::make_pair("application", "manifest"), + std::make_pair("category", "intent-filter"), + std::make_pair("compatible-screens", "manifest"), + std::make_pair("feature-group", "manifest"), + std::make_pair("input-type", "supports-input"), + std::make_pair("intent-filter", "activity"), + std::make_pair("intent-filter", "activity-alias"), + std::make_pair("intent-filter", "service"), + std::make_pair("intent-filter", "receiver"), + std::make_pair("intent-filter", "provider"), + std::make_pair("manifest", ""), + std::make_pair("meta-data", "activity"), + std::make_pair("meta-data", "activity-alias"), + std::make_pair("meta-data", "application"), + std::make_pair("meta-data", "service"), + std::make_pair("meta-data", "receiver"), + std::make_pair("meta-data", "provider"), + std::make_pair("original-package", "manifest"), + std::make_pair("overlay", "manifest"), + std::make_pair("package-verifier", "manifest"), + std::make_pair("permission", "manifest"), + std::make_pair("property", "activity"), + std::make_pair("property", "activity-alias"), + std::make_pair("property", "application"), + std::make_pair("property", "service"), + std::make_pair("property", "receiver"), + std::make_pair("property", "provider"), + std::make_pair("provider", "application"), + std::make_pair("receiver", "application"), + std::make_pair("required-feature", "uses-permission"), + std::make_pair("required-not-feature", "uses-permission"), + std::make_pair("screen", "compatible-screens"), + std::make_pair("service", "application"), + std::make_pair("sdk-library", "application"), + std::make_pair("static-library", "application"), + std::make_pair("supports-gl-texture", "manifest"), + std::make_pair("supports-input", "manifest"), + std::make_pair("supports-screens", "manifest"), + std::make_pair("uses-configuration", "manifest"), + std::make_pair("uses-feature", "feature-group"), + std::make_pair("uses-feature", "manifest"), + std::make_pair("uses-library", "application"), + std::make_pair("uses-native-library", "application"), + std::make_pair("uses-package", "application"), + std::make_pair("uses-permission", "manifest"), + std::make_pair("uses-permission-sdk-23", "manifest"), + std::make_pair("uses-sdk", "manifest"), + std::make_pair("uses-sdk-library", "application"), + std::make_pair("uses-static-library", "application"), + }; + bool is_valid_tag = std::find(kValidChildParentTags.begin(), kValidChildParentTags.end(), + std::make_pair<std::string_view, std::string_view>( + el->name, parent_tag)) != kValidChildParentTags.end(); // Attempt to map the xml tag to a element inflater std::unique_ptr<ManifestExtractor::Element> element; auto check = kTagCheck.find(el->name); - if (check != kTagCheck.end()) { + if (check != kTagCheck.end() && is_valid_tag) { element = check->second(); + element->featured_ = true; } else { element = util::make_unique<ManifestExtractor::Element>(); } @@ -2999,13 +3045,14 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( return element; } -std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Visit(xml::Element* el) { - auto element = ManifestExtractor::Element::Inflate(this, el); +std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Visit( + xml::Element* el, const std::string& parent_tag) { + auto element = ManifestExtractor::Element::Inflate(this, el, parent_tag); parent_stack_.insert(parent_stack_.begin(), element.get()); // Process the element and recursively visit the children for (xml::Element* child : el->GetChildElements()) { - auto v = Visit(child); + auto v = Visit(child, el->name); element->AddChild(v); } diff --git a/tools/aapt2/integration-tests/DumpTest/built_with_aapt.apk b/tools/aapt2/integration-tests/DumpTest/built_with_aapt.apk Binary files differnew file mode 100644 index 000000000000..090ebe5687dd --- /dev/null +++ b/tools/aapt2/integration-tests/DumpTest/built_with_aapt.apk diff --git a/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt b/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt new file mode 100644 index 000000000000..cc0b3bf5d2fb --- /dev/null +++ b/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt @@ -0,0 +1,11 @@ +package: name='com.aapt.app' versionCode='222' versionName='222' platformBuildVersionName='12' platformBuildVersionCode='32' compileSdkVersion='32' compileSdkVersionCodename='12' +sdkVersion:'22' +targetSdkVersion:'32' +application: label='App' icon='' +feature-group: label='' + uses-feature: name='android.hardware.faketouch' + uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps' +supports-screens: 'small' 'normal' 'large' 'xlarge' +supports-any-density: 'true' +locales: +densities: diff --git a/tools/aapt2/integration-tests/DumpTest/components_expected.txt b/tools/aapt2/integration-tests/DumpTest/components_expected.txt index 79b6706e4a9f..9c81fb83ca15 100644 --- a/tools/aapt2/integration-tests/DumpTest/components_expected.txt +++ b/tools/aapt2/integration-tests/DumpTest/components_expected.txt @@ -36,6 +36,7 @@ provides-component:'ime' provides-component:'wallpaper' provides-component:'accessibility' provides-component:'print-service' +provides-component:'payment' provides-component:'search' provides-component:'document-provider' provides-component:'notification-listener' diff --git a/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt b/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt index 4aed4afa2753..ebb302e7493e 100644 --- a/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt +++ b/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt @@ -87,6 +87,7 @@ badging { provided_components: "wallpaper" provided_components: "accessibility" provided_components: "print-service" + provided_components: "payment" provided_components: "search" provided_components: "document-provider" provided_components: "notification-listener" diff --git a/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt b/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt index c783f47f8142..e5cf83408457 100644 --- a/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt +++ b/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt @@ -87,6 +87,7 @@ badging { provided_components: "wallpaper" provided_components: "accessibility" provided_components: "print-service" + provided_components: "payment" provided_components: "search" provided_components: "document-provider" provided_components: "notification-listener" |