diff options
author | Adam Lesinski <adamlesinski@google.com> | 2014-12-05 19:16:27 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-12-05 19:16:27 +0000 |
commit | 7e74da3172cb175dd1fe4e1ffb48d8f7914225ca (patch) | |
tree | 7eed72fd8d79c84dabbcf50f0f08822a06303822 | |
parent | 7abdfaa742b64ab5a68e0cede51f4fe30fd21662 (diff) | |
parent | e97908d32ee8ea80138d085260a0eac93841c722 (diff) | |
download | frameworks_base-7e74da3172cb175dd1fe4e1ffb48d8f7914225ca.zip frameworks_base-7e74da3172cb175dd1fe4e1ffb48d8f7914225ca.tar.gz frameworks_base-7e74da3172cb175dd1fe4e1ffb48d8f7914225ca.tar.bz2 |
am e97908d3: Merge commit \'0953ab27\' into manualmerge
* commit 'e97908d32ee8ea80138d085260a0eac93841c722':
AAPT: Move private attrs to new type for framework
-rw-r--r-- | include/androidfw/ResourceTypes.h | 3 | ||||
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 105 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.cpp | 171 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.h | 15 |
4 files changed, 224 insertions, 70 deletions
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index ba72cd5..de73254 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -1826,6 +1826,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); diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 01d3f09..2b8e792 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -4316,6 +4316,9 @@ nope: 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]; @@ -4330,66 +4333,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; - } - - ti += group->packages[pi]->typeIdOffset; + const char16_t* targetType = type; + size_t targetTypeLen = typeLen; - const TypeList& typeList = group->types[ti]; - if (typeList.isEmpty()) { - if (kDebugTableNoisy) { - ALOGI("Expected type structure not found in package %s for index %zd\n", - String8(group->name).string(), ti); + do { + ssize_t ti = group->packages[pi]->typeStrings.indexOfString( + targetType, targetTypeLen); + if (ti < 0) { + continue; } - continue; - } - 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; + ti += group->packages[pi]->typeIdOffset; + + 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; } diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 69f1ec3..e91a376 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -12,6 +12,7 @@ #include "ResourceIdCache.h" #include "SdkConstants.h" +#include <algorithm> #include <androidfw/ResourceTypes.h> #include <utils/ByteOrder.h> #include <utils/TypeHelpers.h> @@ -36,6 +37,8 @@ static const bool kPrintStringMetrics = true; static const bool kPrintStringMetrics = false; #endif +static const char* kAttrPrivateType = "^attr-private"; + status_t compileXmlFile(const Bundle* bundle, const sp<AaptAssets>& assets, const String16& resourceName, @@ -2153,8 +2156,16 @@ uint32_t ResourceTable::getResId(const String16& package, if (p == NULL) return 0; sp<Type> t = p->getTypes().valueFor(type); if (t == NULL) return 0; - sp<ConfigList> c = t->getConfigs().valueFor(name); - if (c == 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; @@ -2293,7 +2304,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) return 0; + 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); @@ -2497,6 +2516,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) { @@ -2567,15 +2590,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++) { @@ -2613,9 +2641,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; } @@ -2981,6 +3015,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); } @@ -3011,12 +3049,16 @@ 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 != NULL ? t->getUniqueConfigs().size() : 0; + SortedVector<ConfigDescription> uniqueConfigs; + if (t != NULL) { + uniqueConfigs = t->getUniqueConfigs(); + } const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; + const size_t NC = uniqueConfigs.size(); for (size_t ci=0; ci<NC; ci++) { - ConfigDescription config = t->getUniqueConfigs().itemAt(ci); + const ConfigDescription& config = uniqueConfigs[ci]; if (kIsDebug) { printf("Writing config %zu config: imsi:%d/%d lang:%c%c cnt:%c%c " @@ -3092,7 +3134,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*) @@ -3127,9 +3172,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); - 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)); + 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; } } @@ -3841,11 +3888,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(); @@ -3872,11 +3953,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); @@ -4049,6 +4129,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) { diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index db392c8..81590bc 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -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; } @@ -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; @@ -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, |