Merge commit '0953ab27' into manualmerge
Change-Id: I36dea45f7571096136ea7bda5e2680bd85a0df32
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user