Merge commit '0953ab27' into manualmerge

Change-Id: I36dea45f7571096136ea7bda5e2680bd85a0df32
This commit is contained in:
Adam Lesinski
2014-12-05 11:06:21 -08:00
4 changed files with 227 additions and 73 deletions

View File

@@ -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);

View File

@@ -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;
}
const char16_t* targetType = type;
size_t targetTypeLen = typeLen;
ti += group->packages[pi]->typeIdOffset;
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);
}
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) {
do {
ssize_t ti = group->packages[pi]->typeStrings.indexOfString(
targetType, targetTypeLen);
if (ti < 0) {
continue;
}
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;
}
ti += group->packages[pi]->typeIdOffset;
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;
if (fakePublic) {
*outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;
}
}
return resId;
}
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];
const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen);
if (ei < 0) {
continue;
}
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 (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;
}

View File

@@ -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) {

View File

@@ -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,