diff options
author | Xin Li <delphij@google.com> | 2020-09-09 20:21:10 -0700 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2020-09-09 20:21:10 -0700 |
commit | c64112eb974e9aa7638aead998f07a868acfb5a7 (patch) | |
tree | 503334edcee47bfd9f7a76d987d881992ecae9aa /cmds/idmap2/libidmap2/ResourceUtils.cpp | |
parent | 104d2f92b3911576c284ddb0adf78148359883d2 (diff) | |
parent | 14a6871e432e163533a320516ace97bd67d9c3a0 (diff) |
Merge Android R
Bug: 168057903
Merged-In: Ice3e441cc9c0df8d0a6acc016bb74375e081bd67
Change-Id: I1d85742f594be2007c99841b290e502b6ede624e
Diffstat (limited to 'cmds/idmap2/libidmap2/ResourceUtils.cpp')
-rw-r--r-- | cmds/idmap2/libidmap2/ResourceUtils.cpp | 118 |
1 files changed, 88 insertions, 30 deletions
diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp index dce83e35978d..98d026bc70dc 100644 --- a/cmds/idmap2/libidmap2/ResourceUtils.cpp +++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp @@ -22,18 +22,56 @@ #include "androidfw/StringPiece.h" #include "androidfw/Util.h" #include "idmap2/Result.h" -#include "idmap2/Xml.h" +#include "idmap2/XmlParser.h" #include "idmap2/ZipFile.h" using android::StringPiece16; using android::idmap2::Result; -using android::idmap2::Xml; +using android::idmap2::XmlParser; using android::idmap2::ZipFile; using android::util::Utf16ToUtf8; namespace android::idmap2::utils { -Result<std::string> ResToTypeEntryName(const AssetManager2& am, ResourceId resid) { +bool IsReference(uint8_t data_type) { + return data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE; +} + +StringPiece DataTypeToString(uint8_t data_type) { + switch (data_type) { + case Res_value::TYPE_NULL: + return "null"; + case Res_value::TYPE_REFERENCE: + return "reference"; + case Res_value::TYPE_ATTRIBUTE: + return "attribute"; + case Res_value::TYPE_STRING: + return "string"; + case Res_value::TYPE_FLOAT: + return "float"; + case Res_value::TYPE_DIMENSION: + return "dimension"; + case Res_value::TYPE_FRACTION: + return "fraction"; + case Res_value::TYPE_DYNAMIC_REFERENCE: + return "reference (dynamic)"; + case Res_value::TYPE_DYNAMIC_ATTRIBUTE: + return "attribute (dynamic)"; + case Res_value::TYPE_INT_DEC: + case Res_value::TYPE_INT_HEX: + return "integer"; + case Res_value::TYPE_INT_BOOLEAN: + return "boolean"; + case Res_value::TYPE_INT_COLOR_ARGB8: + case Res_value::TYPE_INT_COLOR_RGB8: + case Res_value::TYPE_INT_COLOR_RGB4: + return "color"; + default: + return "unknown"; + } +} + +Result<std::string> ResToTypeEntryName(const AssetManager2& am, uint32_t resid) { AssetManager2::ResourceName name; if (!am.GetResourceName(resid, &name)) { return Error("no resource 0x%08x in asset manager", resid); @@ -65,52 +103,72 @@ Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path, return Error("failed to uncompress AndroidManifest.xml from %s", path.c_str()); } - std::unique_ptr<const Xml> xml = Xml::Create(entry->buf, entry->size); + Result<std::unique_ptr<const XmlParser>> xml = XmlParser::Create(entry->buf, entry->size); if (!xml) { return Error("failed to parse AndroidManifest.xml from %s", path.c_str()); } + auto manifest_it = (*xml)->tree_iterator(); + if (manifest_it->event() != XmlParser::Event::START_TAG || manifest_it->name() != "manifest") { + return Error("root element tag is not <manifest> in AndroidManifest.xml of %s", path.c_str()); + } + + auto overlay_it = std::find_if(manifest_it.begin(), manifest_it.end(), [](const auto& it) { + return it.event() == XmlParser::Event::START_TAG && it.name() == "overlay"; + }); + OverlayManifestInfo info{}; - const auto tag = xml->FindTag("overlay"); - if (!tag) { - if (assert_overlay) { - return Error("<overlay> missing from AndroidManifest.xml of %s", path.c_str()); + if (overlay_it == manifest_it.end()) { + if (!assert_overlay) { + return info; } - return info; + return Error("<overlay> missing from AndroidManifest.xml of %s", path.c_str()); } - auto iter = tag->find("targetPackage"); - if (iter == tag->end()) { - if (assert_overlay) { - return Error("android:targetPackage missing from <overlay> of %s", path.c_str()); - } + if (auto result_str = overlay_it->GetAttributeStringValue("targetPackage")) { + info.target_package = *result_str; } else { - info.target_package = iter->second; + return Error("android:targetPackage missing from <overlay> of %s: %s", path.c_str(), + result_str.GetErrorMessage().c_str()); } - iter = tag->find("targetName"); - if (iter != tag->end()) { - info.target_name = iter->second; + if (auto result_str = overlay_it->GetAttributeStringValue("targetName")) { + info.target_name = *result_str; } - iter = tag->find("isStatic"); - if (iter != tag->end()) { - info.is_static = std::stoul(iter->second) != 0U; + if (auto result_value = overlay_it->GetAttributeValue("resourcesMap")) { + if (IsReference((*result_value).dataType)) { + info.resource_mapping = (*result_value).data; + } else { + return Error("android:resourcesMap is not a reference in AndroidManifest.xml of %s", + path.c_str()); + } } - iter = tag->find("priority"); - if (iter != tag->end()) { - info.priority = std::stoi(iter->second); + if (auto result_value = overlay_it->GetAttributeValue("isStatic")) { + if ((*result_value).dataType >= Res_value::TYPE_FIRST_INT && + (*result_value).dataType <= Res_value::TYPE_LAST_INT) { + info.is_static = (*result_value).data != 0U; + } else { + return Error("android:isStatic is not a boolean in AndroidManifest.xml of %s", path.c_str()); + } + } + + if (auto result_value = overlay_it->GetAttributeValue("priority")) { + if ((*result_value).dataType >= Res_value::TYPE_FIRST_INT && + (*result_value).dataType <= Res_value::TYPE_LAST_INT) { + info.priority = (*result_value).data; + } else { + return Error("android:priority is not an integer in AndroidManifest.xml of %s", path.c_str()); + } } - iter = tag->find("requiredSystemPropertyName"); - if (iter != tag->end()) { - info.requiredSystemPropertyName = iter->second; + if (auto result_str = overlay_it->GetAttributeStringValue("requiredSystemPropertyName")) { + info.requiredSystemPropertyName = *result_str; } - iter = tag->find("requiredSystemPropertyValue"); - if (iter != tag->end()) { - info.requiredSystemPropertyValue = iter->second; + if (auto result_str = overlay_it->GetAttributeStringValue("requiredSystemPropertyValue")) { + info.requiredSystemPropertyValue = *result_str; } return info; |