summaryrefslogtreecommitdiff
path: root/cmds/idmap2/idmap2/Lookup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/idmap2/idmap2/Lookup.cpp')
-rw-r--r--cmds/idmap2/idmap2/Lookup.cpp126
1 files changed, 70 insertions, 56 deletions
diff --git a/cmds/idmap2/idmap2/Lookup.cpp b/cmds/idmap2/idmap2/Lookup.cpp
index b7ae9d090cee..c44170928992 100644
--- a/cmds/idmap2/idmap2/Lookup.cpp
+++ b/cmds/idmap2/idmap2/Lookup.cpp
@@ -33,9 +33,10 @@
#include "androidfw/Util.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/Idmap.h"
+#include "idmap2/ResourceUtils.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
-#include "idmap2/Xml.h"
+#include "idmap2/XmlParser.h"
#include "idmap2/ZipFile.h"
#include "utils/String16.h"
#include "utils/String8.h"
@@ -57,8 +58,7 @@ using android::idmap2::IdmapHeader;
using android::idmap2::ResourceId;
using android::idmap2::Result;
using android::idmap2::Unit;
-using android::idmap2::Xml;
-using android::idmap2::ZipFile;
+using android::idmap2::utils::ExtractOverlayManifestInfo;
using android::util::Utf16ToUtf8;
namespace {
@@ -85,76 +85,90 @@ Result<ResourceId> WARN_UNUSED ParseResReference(const AssetManager2& am, const
return Error("failed to obtain resource id for %s", res.c_str());
}
-Result<std::string> WARN_UNUSED GetValue(const AssetManager2& am, ResourceId resid) {
- Res_value value;
- ResTable_config config;
- uint32_t flags;
- ApkAssetsCookie cookie = am.GetResource(resid, false, 0, &value, &config, &flags);
- if (cookie == kInvalidCookie) {
- return Error("no resource 0x%08x in asset manager", resid);
- }
-
- std::string out;
-
- // TODO(martenkongstad): use optional parameter GetResource(..., std::string*
- // stacktrace = NULL) instead
- out.append(StringPrintf("cookie=%d ", cookie));
-
- out.append("config='");
- out.append(config.toString().c_str());
- out.append("' value=");
-
+void PrintValue(AssetManager2* const am, const Res_value& value, const ApkAssetsCookie& cookie,
+ std::string* const out) {
switch (value.dataType) {
case Res_value::TYPE_INT_DEC:
- out.append(StringPrintf("%d", value.data));
+ out->append(StringPrintf("%d", value.data));
break;
case Res_value::TYPE_INT_HEX:
- out.append(StringPrintf("0x%08x", value.data));
+ out->append(StringPrintf("0x%08x", value.data));
break;
case Res_value::TYPE_INT_BOOLEAN:
- out.append(value.data != 0 ? "true" : "false");
+ out->append(value.data != 0 ? "true" : "false");
break;
case Res_value::TYPE_STRING: {
- const ResStringPool* pool = am.GetStringPoolForCookie(cookie);
+ const ResStringPool* pool = am->GetStringPoolForCookie(cookie);
+ out->append("\"");
size_t len;
if (pool->isUTF8()) {
const char* str = pool->string8At(value.data, &len);
- out.append(str, len);
+ out->append(str, len);
} else {
const char16_t* str16 = pool->stringAt(value.data, &len);
- out += Utf16ToUtf8(StringPiece16(str16, len));
+ out->append(Utf16ToUtf8(StringPiece16(str16, len)));
}
+ out->append("\"");
} break;
default:
- out.append(StringPrintf("dataType=0x%02x data=0x%08x", value.dataType, value.data));
+ out->append(StringPrintf("dataType=0x%02x data=0x%08x", value.dataType, value.data));
break;
}
- return out;
}
-Result<std::string> GetTargetPackageNameFromManifest(const std::string& apk_path) {
- const auto zip = ZipFile::Open(apk_path);
- if (!zip) {
- return Error("failed to open %s as zip", apk_path.c_str());
- }
- const auto entry = zip->Uncompress("AndroidManifest.xml");
- if (!entry) {
- return Error("failed to uncompress AndroidManifest.xml in %s", apk_path.c_str());
- }
- const auto xml = Xml::Create(entry->buf, entry->size);
- if (!xml) {
- return Error("failed to create XML buffer");
- }
- const auto tag = xml->FindTag("overlay");
- if (!tag) {
- return Error("failed to find <overlay> tag");
+Result<std::string> WARN_UNUSED GetValue(AssetManager2* const am, ResourceId resid) {
+ Res_value value;
+ ResTable_config config;
+ uint32_t flags;
+ ApkAssetsCookie cookie = am->GetResource(resid, true, 0, &value, &config, &flags);
+ if (cookie == kInvalidCookie) {
+ return Error("no resource 0x%08x in asset manager", resid);
}
- const auto iter = tag->find("targetPackage");
- if (iter == tag->end()) {
- return Error("failed to find targetPackage attribute");
+
+ std::string out;
+
+ // TODO(martenkongstad): use optional parameter GetResource(..., std::string*
+ // stacktrace = NULL) instead
+ out.append(StringPrintf("cookie=%d ", cookie));
+
+ out.append("config='");
+ out.append(config.toString().c_str());
+ out.append("' value=");
+
+ if (value.dataType == Res_value::TYPE_REFERENCE) {
+ const android::ResolvedBag* bag = am->GetBag(static_cast<uint32_t>(value.data));
+ if (bag == nullptr) {
+ out.append(StringPrintf("dataType=0x%02x data=0x%08x", value.dataType, value.data));
+ return out;
+ }
+ out.append("[");
+ Res_value bag_val;
+ ResTable_config selected_config;
+ uint32_t flags;
+ uint32_t ref;
+ ApkAssetsCookie bag_cookie;
+ for (size_t i = 0; i < bag->entry_count; ++i) {
+ const android::ResolvedBag::Entry& entry = bag->entries[i];
+ bag_val = entry.value;
+ bag_cookie = am->ResolveReference(entry.cookie, &bag_val, &selected_config, &flags, &ref);
+ if (bag_cookie == kInvalidCookie) {
+ out.append(
+ StringPrintf("Error: dataType=0x%02x data=0x%08x", bag_val.dataType, bag_val.data));
+ continue;
+ }
+ PrintValue(am, bag_val, bag_cookie, &out);
+ if (i != bag->entry_count - 1) {
+ out.append(", ");
+ }
+ }
+ out.append("]");
+ } else {
+ PrintValue(am, value, cookie, &out);
}
- return iter->second;
+
+ return out;
}
+
} // namespace
Result<Unit> Lookup(const std::vector<std::string>& args) {
@@ -202,12 +216,12 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
}
apk_assets.push_back(std::move(target_apk));
- const Result<std::string> package_name =
- GetTargetPackageNameFromManifest(idmap_header->GetOverlayPath().to_string());
- if (!package_name) {
- return Error("failed to parse android:targetPackage from overlay manifest");
+ auto manifest_info = ExtractOverlayManifestInfo(idmap_header->GetOverlayPath().to_string(),
+ true /* assert_overlay */);
+ if (!manifest_info) {
+ return manifest_info.GetError();
}
- target_package_name = *package_name;
+ target_package_name = (*manifest_info).target_package;
} else if (target_path != idmap_header->GetTargetPath()) {
return Error("different target APKs (expected target APK %s but %s has target APK %s)",
target_path.c_str(), idmap_path.c_str(),
@@ -235,7 +249,7 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
return Error(resid.GetError(), "failed to parse resource ID");
}
- const Result<std::string> value = GetValue(am, *resid);
+ const Result<std::string> value = GetValue(&am, *resid);
if (!value) {
return Error(value.GetError(), "resource 0x%08x not found", *resid);
}