diff options
Diffstat (limited to 'libs/androidfw/ResourceTypes.cpp')
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 103 |
1 files changed, 57 insertions, 46 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 6dfb4dc..d7b9765 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -4173,6 +4173,9 @@ nope: String8(name, nameLen).string(), String8(package, packageLen).string())); + const String16 attr("attr"); + const String16 attrPrivate("^attr-private"); + const size_t NG = mPackageGroups.size(); for (size_t ig=0; ig<NG; ig++) { const PackageGroup* group = mPackageGroups[ig]; @@ -4185,64 +4188,72 @@ nope: const size_t packageCount = group->packages.size(); for (size_t pi = 0; pi < packageCount; pi++) { - ssize_t ti = group->packages[pi]->typeStrings.indexOfString(type, typeLen); - if (ti < 0) { - continue; - } + const char16_t* targetType = type; + size_t targetTypeLen = typeLen; - ti += group->packages[pi]->typeIdOffset; + do { + ssize_t ti = group->packages[pi]->typeStrings.indexOfString( + targetType, targetTypeLen); + if (ti < 0) { + continue; + } - const TypeList& typeList = group->types[ti]; - if (typeList.isEmpty()) { - TABLE_NOISY(printf("Expected type structure not found in package %s for index %d\n", - String8(group->name).string(), ti)); - continue; - } + ti += group->packages[pi]->typeIdOffset; - const size_t typeCount = typeList.size(); - for (size_t i = 0; i < typeCount; i++) { - const Type* t = typeList[i]; - const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen); - if (ei < 0) { - continue; + const uint32_t identifier = findEntry(group, ti, name, nameLen, + outTypeSpecFlags); + if (identifier != 0) { + if (fakePublic && outTypeSpecFlags) { + *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC; + } + return identifier; } + } while (strzcmp16(attr.string(), attr.size(), targetType, targetTypeLen) == 0 + && (targetType = attrPrivate.string()) + && (targetTypeLen = attrPrivate.size()) + ); + } + break; + } + return 0; +} - const size_t configCount = t->configs.size(); - for (size_t j = 0; j < configCount; j++) { - const TypeVariant tv(t->configs[j]); - for (TypeVariant::iterator iter = tv.beginEntries(); - iter != tv.endEntries(); - iter++) { - const ResTable_entry* entry = *iter; - if (entry == NULL) { - continue; - } +uint32_t ResTable::findEntry(const PackageGroup* group, ssize_t typeIndex, const char16_t* name, + size_t nameLen, uint32_t* outTypeSpecFlags) const { + const TypeList& typeList = group->types[typeIndex]; + const size_t typeCount = typeList.size(); + for (size_t i = 0; i < typeCount; i++) { + const Type* t = typeList[i]; + const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen); + if (ei < 0) { + continue; + } - if (dtohl(entry->key.index) == (size_t) ei) { - uint32_t resId = Res_MAKEID(group->id - 1, ti, iter.index()); - if (outTypeSpecFlags) { - Entry result; - if (getEntry(group, ti, iter.index(), NULL, &result) != NO_ERROR) { - ALOGW("Failed to find spec flags for %s:%s/%s (0x%08x)", - String8(group->name).string(), - String8(String16(type, typeLen)).string(), - String8(String16(name, nameLen)).string(), - resId); - return 0; - } - *outTypeSpecFlags = result.specFlags; + const size_t configCount = t->configs.size(); + for (size_t j = 0; j < configCount; j++) { + const TypeVariant tv(t->configs[j]); + for (TypeVariant::iterator iter = tv.beginEntries(); + iter != tv.endEntries(); + iter++) { + const ResTable_entry* entry = *iter; + if (entry == NULL) { + continue; + } - if (fakePublic) { - *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC; - } - } - return resId; + if (dtohl(entry->key.index) == (size_t) ei) { + uint32_t resId = Res_MAKEID(group->id - 1, typeIndex, iter.index()); + if (outTypeSpecFlags) { + Entry result; + if (getEntry(group, typeIndex, iter.index(), NULL, &result) != NO_ERROR) { + ALOGW("Failed to find spec flags for 0x%08x", resId); + return 0; } + *outTypeSpecFlags = result.specFlags; } + return resId; } } } - break; } return 0; } |