Loading include/androidfw/ResourceTypes.h +3 −0 Original line number Diff line number Diff line Loading @@ -1828,6 +1828,9 @@ private: const ResTable_config* config, Entry* outEntry) const; uint32_t findEntry(const PackageGroup* group, ssize_t typeIndex, const char16_t* name, size_t nameLen, uint32_t* outTypeSpecFlags) const; status_t parsePackage( const ResTable_package* const pkg, const Header* const header); Loading libs/androidfw/ResourceTypes.cpp +57 −46 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -4185,20 +4188,39 @@ 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); const char16_t* targetType = type; size_t targetTypeLen = typeLen; do { ssize_t ti = group->packages[pi]->typeStrings.indexOfString( targetType, targetTypeLen); if (ti < 0) { continue; } ti += group->packages[pi]->typeIdOffset; 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; 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; } 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]; Loading @@ -4219,31 +4241,20 @@ nope: } if (dtohl(entry->key.index) == (size_t) ei) { uint32_t resId = Res_MAKEID(group->id - 1, ti, iter.index()); uint32_t resId = Res_MAKEID(group->id - 1, typeIndex, 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); 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; if (fakePublic) { *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC; } } return resId; } } } } } break; } return 0; } Loading tools/aapt/ResourceTable.cpp +150 −18 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "ResourceIdCache.h" #include "SdkConstants.h" #include <algorithm> #include <androidfw/ResourceTypes.h> #include <utils/ByteOrder.h> #include <utils/TypeHelpers.h> Loading @@ -19,6 +20,8 @@ #define NOISY(x) //x static const char* kAttrPrivateType = "^attr-private"; status_t compileXmlFile(const Bundle* bundle, const sp<AaptAssets>& assets, const String16& resourceName, Loading Loading @@ -2132,7 +2135,15 @@ uint32_t ResourceTable::getResId(const String16& package, sp<Type> t = p->getTypes().valueFor(type); if (t == NULL) return 0; sp<ConfigList> c = t->getConfigs().valueFor(name); if (c == NULL) { if (type != String16("attr")) { return 0; } t = p->getTypes().valueFor(String16(kAttrPrivateType)); if (t == NULL) return 0; c = t->getConfigs().valueFor(name); if (c == NULL) return 0; } int32_t ei = c->getEntryIndex(); if (ei < 0) return 0; Loading Loading @@ -2266,7 +2277,15 @@ uint32_t ResourceTable::getCustomResource( sp<Type> t = p->getTypes().valueFor(type); if (t == NULL) return 0; sp<ConfigList> c = t->getConfigs().valueFor(name); if (c == NULL) { if (type != String16("attr")) { return 0; } t = p->getTypes().valueFor(String16(kAttrPrivateType)); if (t == NULL) return 0; c = t->getConfigs().valueFor(name); if (c == NULL) return 0; } int32_t ei = c->getEntryIndex(); if (ei < 0) return 0; return getResId(p, t, ei); Loading Loading @@ -2470,6 +2489,10 @@ status_t ResourceTable::assignResourceIds() continue; } if (mPackageType == System) { p->movePrivateAttrs(); } // This has no sense for packages being built as AppFeature (aka with a non-zero offset). status_t err = p->applyPublicTypeOrder(); if (err != NO_ERROR && firstError == NO_ERROR) { Loading Loading @@ -2540,15 +2563,20 @@ status_t ResourceTable::assignResourceIds() } } // Assign resource IDs to keys in bags... for (size_t ti = 0; ti < typeCount; ti++) { sp<Type> t = p->getOrderedTypes().itemAt(ti); if (t == NULL) { continue; } const size_t N = t->getOrderedConfigs().size(); for (size_t ci=0; ci<N; ci++) { sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); if (c == NULL) { continue; } //printf("Ordered config #%d: %p\n", ci, c.get()); const size_t N = c->getEntries().size(); for (size_t ei=0; ei<N; ei++) { Loading Loading @@ -2586,9 +2614,15 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { if (t == NULL) { continue; } const size_t N = t->getOrderedConfigs().size(); sp<AaptSymbols> typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); sp<AaptSymbols> typeSymbols; if (t->getName() == String16(kAttrPrivateType)) { typeSymbols = outSymbols->addNestedSymbol(String8("attr"), t->getPos()); } else { typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); } if (typeSymbols == NULL) { return UNKNOWN_ERROR; } Loading Loading @@ -2954,6 +2988,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& for (size_t ei=0; ei<N; ei++) { sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); if (cl == NULL) { continue; } if (cl->getPublic()) { typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); } Loading Loading @@ -2984,12 +3022,13 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& // We need to write one type chunk for each configuration for // which we have entries in this type. const size_t NC = t->getUniqueConfigs().size(); const SortedVector<ConfigDescription> uniqueConfigs(t->getUniqueConfigs()); const size_t NC = uniqueConfigs.size(); const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; for (size_t ci=0; ci<NC; ci++) { ConfigDescription config = t->getUniqueConfigs().itemAt(ci); const ConfigDescription& config = uniqueConfigs[ci]; NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " Loading Loading @@ -3061,7 +3100,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& // Build the entries inside of this type. for (size_t ei=0; ei<N; ei++) { sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); sp<Entry> e = cl->getEntries().valueFor(config); sp<Entry> e = NULL; if (cl != NULL) { e = cl->getEntries().valueFor(config); } // Set the offset for this entry in its type. uint32_t* index = (uint32_t*) Loading Loading @@ -3096,9 +3138,11 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& for (size_t i = 0; i < N; ++i) { if (!validResources[i]) { sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); if (c != NULL) { fprintf(stderr, "%s: no entries written for %s/%s (0x%08x)\n", log_prefix, String8(typeName).string(), String8(c->getName()).string(), Res_MAKEID(p->getAssignedId() - 1, ti, i)); } missing_entry = true; } } Loading Loading @@ -3807,11 +3851,45 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, */ } mUniqueConfigs.add(cdesc); return e; } sp<ResourceTable::ConfigList> ResourceTable::Type::removeEntry(const String16& entry) { ssize_t idx = mConfigs.indexOfKey(entry); if (idx < 0) { return NULL; } sp<ConfigList> removed = mConfigs.valueAt(idx); mConfigs.removeItemsAt(idx); Vector<sp<ConfigList> >::iterator iter = std::find( mOrderedConfigs.begin(), mOrderedConfigs.end(), removed); if (iter != mOrderedConfigs.end()) { mOrderedConfigs.erase(iter); } mPublic.removeItem(entry); return removed; } SortedVector<ConfigDescription> ResourceTable::Type::getUniqueConfigs() const { SortedVector<ConfigDescription> unique; const size_t entryCount = mOrderedConfigs.size(); for (size_t i = 0; i < entryCount; i++) { if (mOrderedConfigs[i] == NULL) { continue; } const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configs = mOrderedConfigs[i]->getEntries(); const size_t configCount = configs.size(); for (size_t j = 0; j < configCount; j++) { unique.add(configs.keyAt(j)); } } return unique; } status_t ResourceTable::Type::applyPublicEntryOrder() { size_t N = mOrderedConfigs.size(); Loading @@ -3838,11 +3916,10 @@ status_t ResourceTable::Type::applyPublicEntryOrder() //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); if (e->getName() == name) { if (idx >= (int32_t)mOrderedConfigs.size()) { p.sourcePos.error("Public entry identifier 0x%x entry index " "is larger than available symbols (index %d, total symbols %d).\n", p.ident, idx, mOrderedConfigs.size()); hasError = true; } else if (mOrderedConfigs.itemAt(idx) == NULL) { mOrderedConfigs.resize(idx + 1); } if (mOrderedConfigs.itemAt(idx) == NULL) { e->setPublic(true); e->setPublicSourcePos(p.sourcePos); mOrderedConfigs.replaceAt(e, idx); Loading Loading @@ -4018,6 +4095,61 @@ status_t ResourceTable::Package::applyPublicTypeOrder() return NO_ERROR; } void ResourceTable::Package::movePrivateAttrs() { sp<Type> attr = mTypes.valueFor(String16("attr")); if (attr == NULL) { // Nothing to do. return; } Vector<sp<ConfigList> > privateAttrs; bool hasPublic = false; const Vector<sp<ConfigList> >& configs = attr->getOrderedConfigs(); const size_t configCount = configs.size(); for (size_t i = 0; i < configCount; i++) { if (configs[i] == NULL) { continue; } if (attr->isPublic(configs[i]->getName())) { hasPublic = true; } else { privateAttrs.add(configs[i]); } } // Only if we have public attributes do we create a separate type for // private attributes. if (!hasPublic) { return; } // Create a new type for private attributes. sp<Type> privateAttrType = getType(String16(kAttrPrivateType), SourcePos()); const size_t privateAttrCount = privateAttrs.size(); for (size_t i = 0; i < privateAttrCount; i++) { const sp<ConfigList>& cl = privateAttrs[i]; // Remove the private attributes from their current type. attr->removeEntry(cl->getName()); // Add it to the new type. const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = cl->getEntries(); const size_t entryCount = entries.size(); for (size_t j = 0; j < entryCount; j++) { const sp<Entry>& oldEntry = entries[j]; sp<Entry> entry = privateAttrType->getEntry( cl->getName(), oldEntry->getPos(), &entries.keyAt(j)); *entry = *oldEntry; } // Move the symbols to the new type. } } sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) { if (package != mAssetsPackage) { Loading tools/aapt/ResourceTable.h +11 −4 Original line number Diff line number Diff line Loading @@ -470,6 +470,14 @@ public: bool overlay = false, bool autoAddOverlay = false); bool isPublic(const String16& entry) const { return mPublic.indexOfKey(entry) >= 0; } sp<ConfigList> removeEntry(const String16& entry); SortedVector<ConfigDescription> getUniqueConfigs() const; const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; } int32_t getPublicIndex() const { return mPublicIndex; } Loading @@ -479,19 +487,16 @@ public: status_t applyPublicEntryOrder(); const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; } const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; } const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; } const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; } const SourcePos& getPos() const { return mPos; } private: String16 mName; SourcePos* mFirstPublicSourcePos; DefaultKeyedVector<String16, Public> mPublic; SortedVector<ConfigDescription> mUniqueConfigs; DefaultKeyedVector<String16, sp<ConfigList> > mConfigs; Vector<sp<ConfigList> > mOrderedConfigs; SortedVector<String16> mCanAddEntries; Loading Loading @@ -527,6 +532,8 @@ public: const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; } const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; } void movePrivateAttrs(); private: status_t setStrings(const sp<AaptFile>& data, ResStringPool* strings, Loading Loading
include/androidfw/ResourceTypes.h +3 −0 Original line number Diff line number Diff line Loading @@ -1828,6 +1828,9 @@ private: const ResTable_config* config, Entry* outEntry) const; uint32_t findEntry(const PackageGroup* group, ssize_t typeIndex, const char16_t* name, size_t nameLen, uint32_t* outTypeSpecFlags) const; status_t parsePackage( const ResTable_package* const pkg, const Header* const header); Loading
libs/androidfw/ResourceTypes.cpp +57 −46 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -4185,20 +4188,39 @@ 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); const char16_t* targetType = type; size_t targetTypeLen = typeLen; do { ssize_t ti = group->packages[pi]->typeStrings.indexOfString( targetType, targetTypeLen); if (ti < 0) { continue; } ti += group->packages[pi]->typeIdOffset; 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; 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; } 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]; Loading @@ -4219,31 +4241,20 @@ nope: } if (dtohl(entry->key.index) == (size_t) ei) { uint32_t resId = Res_MAKEID(group->id - 1, ti, iter.index()); uint32_t resId = Res_MAKEID(group->id - 1, typeIndex, 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); 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; if (fakePublic) { *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC; } } return resId; } } } } } break; } return 0; } Loading
tools/aapt/ResourceTable.cpp +150 −18 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "ResourceIdCache.h" #include "SdkConstants.h" #include <algorithm> #include <androidfw/ResourceTypes.h> #include <utils/ByteOrder.h> #include <utils/TypeHelpers.h> Loading @@ -19,6 +20,8 @@ #define NOISY(x) //x static const char* kAttrPrivateType = "^attr-private"; status_t compileXmlFile(const Bundle* bundle, const sp<AaptAssets>& assets, const String16& resourceName, Loading Loading @@ -2132,7 +2135,15 @@ uint32_t ResourceTable::getResId(const String16& package, sp<Type> t = p->getTypes().valueFor(type); if (t == NULL) return 0; sp<ConfigList> c = t->getConfigs().valueFor(name); if (c == NULL) { if (type != String16("attr")) { return 0; } t = p->getTypes().valueFor(String16(kAttrPrivateType)); if (t == NULL) return 0; c = t->getConfigs().valueFor(name); if (c == NULL) return 0; } int32_t ei = c->getEntryIndex(); if (ei < 0) return 0; Loading Loading @@ -2266,7 +2277,15 @@ uint32_t ResourceTable::getCustomResource( sp<Type> t = p->getTypes().valueFor(type); if (t == NULL) return 0; sp<ConfigList> c = t->getConfigs().valueFor(name); if (c == NULL) { if (type != String16("attr")) { return 0; } t = p->getTypes().valueFor(String16(kAttrPrivateType)); if (t == NULL) return 0; c = t->getConfigs().valueFor(name); if (c == NULL) return 0; } int32_t ei = c->getEntryIndex(); if (ei < 0) return 0; return getResId(p, t, ei); Loading Loading @@ -2470,6 +2489,10 @@ status_t ResourceTable::assignResourceIds() continue; } if (mPackageType == System) { p->movePrivateAttrs(); } // This has no sense for packages being built as AppFeature (aka with a non-zero offset). status_t err = p->applyPublicTypeOrder(); if (err != NO_ERROR && firstError == NO_ERROR) { Loading Loading @@ -2540,15 +2563,20 @@ status_t ResourceTable::assignResourceIds() } } // Assign resource IDs to keys in bags... for (size_t ti = 0; ti < typeCount; ti++) { sp<Type> t = p->getOrderedTypes().itemAt(ti); if (t == NULL) { continue; } const size_t N = t->getOrderedConfigs().size(); for (size_t ci=0; ci<N; ci++) { sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); if (c == NULL) { continue; } //printf("Ordered config #%d: %p\n", ci, c.get()); const size_t N = c->getEntries().size(); for (size_t ei=0; ei<N; ei++) { Loading Loading @@ -2586,9 +2614,15 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { if (t == NULL) { continue; } const size_t N = t->getOrderedConfigs().size(); sp<AaptSymbols> typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); sp<AaptSymbols> typeSymbols; if (t->getName() == String16(kAttrPrivateType)) { typeSymbols = outSymbols->addNestedSymbol(String8("attr"), t->getPos()); } else { typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); } if (typeSymbols == NULL) { return UNKNOWN_ERROR; } Loading Loading @@ -2954,6 +2988,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& for (size_t ei=0; ei<N; ei++) { sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); if (cl == NULL) { continue; } if (cl->getPublic()) { typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); } Loading Loading @@ -2984,12 +3022,13 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& // We need to write one type chunk for each configuration for // which we have entries in this type. const size_t NC = t->getUniqueConfigs().size(); const SortedVector<ConfigDescription> uniqueConfigs(t->getUniqueConfigs()); const size_t NC = uniqueConfigs.size(); const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; for (size_t ci=0; ci<NC; ci++) { ConfigDescription config = t->getUniqueConfigs().itemAt(ci); const ConfigDescription& config = uniqueConfigs[ci]; NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " Loading Loading @@ -3061,7 +3100,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& // Build the entries inside of this type. for (size_t ei=0; ei<N; ei++) { sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); sp<Entry> e = cl->getEntries().valueFor(config); sp<Entry> e = NULL; if (cl != NULL) { e = cl->getEntries().valueFor(config); } // Set the offset for this entry in its type. uint32_t* index = (uint32_t*) Loading Loading @@ -3096,9 +3138,11 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& for (size_t i = 0; i < N; ++i) { if (!validResources[i]) { sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); if (c != NULL) { fprintf(stderr, "%s: no entries written for %s/%s (0x%08x)\n", log_prefix, String8(typeName).string(), String8(c->getName()).string(), Res_MAKEID(p->getAssignedId() - 1, ti, i)); } missing_entry = true; } } Loading Loading @@ -3807,11 +3851,45 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, */ } mUniqueConfigs.add(cdesc); return e; } sp<ResourceTable::ConfigList> ResourceTable::Type::removeEntry(const String16& entry) { ssize_t idx = mConfigs.indexOfKey(entry); if (idx < 0) { return NULL; } sp<ConfigList> removed = mConfigs.valueAt(idx); mConfigs.removeItemsAt(idx); Vector<sp<ConfigList> >::iterator iter = std::find( mOrderedConfigs.begin(), mOrderedConfigs.end(), removed); if (iter != mOrderedConfigs.end()) { mOrderedConfigs.erase(iter); } mPublic.removeItem(entry); return removed; } SortedVector<ConfigDescription> ResourceTable::Type::getUniqueConfigs() const { SortedVector<ConfigDescription> unique; const size_t entryCount = mOrderedConfigs.size(); for (size_t i = 0; i < entryCount; i++) { if (mOrderedConfigs[i] == NULL) { continue; } const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configs = mOrderedConfigs[i]->getEntries(); const size_t configCount = configs.size(); for (size_t j = 0; j < configCount; j++) { unique.add(configs.keyAt(j)); } } return unique; } status_t ResourceTable::Type::applyPublicEntryOrder() { size_t N = mOrderedConfigs.size(); Loading @@ -3838,11 +3916,10 @@ status_t ResourceTable::Type::applyPublicEntryOrder() //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); if (e->getName() == name) { if (idx >= (int32_t)mOrderedConfigs.size()) { p.sourcePos.error("Public entry identifier 0x%x entry index " "is larger than available symbols (index %d, total symbols %d).\n", p.ident, idx, mOrderedConfigs.size()); hasError = true; } else if (mOrderedConfigs.itemAt(idx) == NULL) { mOrderedConfigs.resize(idx + 1); } if (mOrderedConfigs.itemAt(idx) == NULL) { e->setPublic(true); e->setPublicSourcePos(p.sourcePos); mOrderedConfigs.replaceAt(e, idx); Loading Loading @@ -4018,6 +4095,61 @@ status_t ResourceTable::Package::applyPublicTypeOrder() return NO_ERROR; } void ResourceTable::Package::movePrivateAttrs() { sp<Type> attr = mTypes.valueFor(String16("attr")); if (attr == NULL) { // Nothing to do. return; } Vector<sp<ConfigList> > privateAttrs; bool hasPublic = false; const Vector<sp<ConfigList> >& configs = attr->getOrderedConfigs(); const size_t configCount = configs.size(); for (size_t i = 0; i < configCount; i++) { if (configs[i] == NULL) { continue; } if (attr->isPublic(configs[i]->getName())) { hasPublic = true; } else { privateAttrs.add(configs[i]); } } // Only if we have public attributes do we create a separate type for // private attributes. if (!hasPublic) { return; } // Create a new type for private attributes. sp<Type> privateAttrType = getType(String16(kAttrPrivateType), SourcePos()); const size_t privateAttrCount = privateAttrs.size(); for (size_t i = 0; i < privateAttrCount; i++) { const sp<ConfigList>& cl = privateAttrs[i]; // Remove the private attributes from their current type. attr->removeEntry(cl->getName()); // Add it to the new type. const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = cl->getEntries(); const size_t entryCount = entries.size(); for (size_t j = 0; j < entryCount; j++) { const sp<Entry>& oldEntry = entries[j]; sp<Entry> entry = privateAttrType->getEntry( cl->getName(), oldEntry->getPos(), &entries.keyAt(j)); *entry = *oldEntry; } // Move the symbols to the new type. } } sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) { if (package != mAssetsPackage) { Loading
tools/aapt/ResourceTable.h +11 −4 Original line number Diff line number Diff line Loading @@ -470,6 +470,14 @@ public: bool overlay = false, bool autoAddOverlay = false); bool isPublic(const String16& entry) const { return mPublic.indexOfKey(entry) >= 0; } sp<ConfigList> removeEntry(const String16& entry); SortedVector<ConfigDescription> getUniqueConfigs() const; const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; } int32_t getPublicIndex() const { return mPublicIndex; } Loading @@ -479,19 +487,16 @@ public: status_t applyPublicEntryOrder(); const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; } const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; } const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; } const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; } const SourcePos& getPos() const { return mPos; } private: String16 mName; SourcePos* mFirstPublicSourcePos; DefaultKeyedVector<String16, Public> mPublic; SortedVector<ConfigDescription> mUniqueConfigs; DefaultKeyedVector<String16, sp<ConfigList> > mConfigs; Vector<sp<ConfigList> > mOrderedConfigs; SortedVector<String16> mCanAddEntries; Loading Loading @@ -527,6 +532,8 @@ public: const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; } const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; } void movePrivateAttrs(); private: status_t setStrings(const sp<AaptFile>& data, ResStringPool* strings, Loading