Merge change 21159

* changes:
  Allow overlays to add resources.
This commit is contained in:
Android (Google) Code Review
2009-08-13 14:34:27 -07:00
3 changed files with 75 additions and 11 deletions

View File

@@ -475,10 +475,8 @@ static bool applyFileOverlay(const sp<AaptAssets>& assets,
}
} else {
// this group doesn't exist (a file that's only in the overlay)
fprintf(stderr, "aapt: error: "
"*** Resource file '%s' exists only in an overlay\n",
overlaySet->keyAt(overlayIndex).string());
return false;
baseSet->add(overlaySet->keyAt(overlayIndex),
overlaySet->valueAt(overlayIndex));
}
}
// this overlay didn't have resources for this type

View File

@@ -663,6 +663,7 @@ status_t compileResourceFile(Bundle* bundle,
const String16 public16("public");
const String16 public_padding16("public-padding");
const String16 private_symbols16("private-symbols");
const String16 add_resource16("add-resource");
const String16 skip16("skip");
const String16 eat_comment16("eat-comment");
@@ -960,6 +961,36 @@ status_t compileResourceFile(Bundle* bundle,
}
continue;
} else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
String16 typeName;
ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
if (typeIdx < 0) {
srcPos.error("A 'type' attribute is required for <add-resource>\n");
hasErrors = localHasErrors = true;
}
typeName = String16(block.getAttributeStringValue(typeIdx, &len));
String16 name;
ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
if (nameIdx < 0) {
srcPos.error("A 'name' attribute is required for <add-resource>\n");
hasErrors = localHasErrors = true;
}
name = String16(block.getAttributeStringValue(nameIdx, &len));
outTable->canAddEntry(srcPos, myPackage, typeName, name);
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
break;
}
}
}
continue;
} else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
@@ -1557,9 +1588,21 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos,
}
#endif
if (overlay && !hasBagOrEntry(package, type, name)) {
sourcePos.error("Can't add new bags in an overlay. See '%s'\n",
String8(name).string());
return UNKNOWN_ERROR;
bool canAdd = false;
sp<Package> p = mPackages.valueFor(package);
if (p != NULL) {
sp<Type> t = p->getTypes().valueFor(type);
if (t != NULL) {
if (t->getCanAddEntries().indexOf(name) >= 0) {
canAdd = true;
}
}
}
if (!canAdd) {
sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
String8(name).string());
return UNKNOWN_ERROR;
}
}
sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
if (e == NULL) {
@@ -1724,6 +1767,15 @@ bool ResourceTable::appendTypeComment(const String16& package,
return false;
}
void ResourceTable::canAddEntry(const SourcePos& pos,
const String16& package, const String16& type, const String16& name)
{
sp<Type> t = getType(package, type, pos);
if (t != NULL) {
t->canAddEntry(name);
}
}
size_t ResourceTable::size() const {
return mPackages.size();
}
@@ -3215,6 +3267,11 @@ status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
return NO_ERROR;
}
void ResourceTable::Type::canAddEntry(const String16& name)
{
mCanAddEntries.add(name);
}
sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
const SourcePos& sourcePos,
const ResTable_config* config,
@@ -3224,9 +3281,10 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
int pos = -1;
sp<ConfigList> c = mConfigs.valueFor(entry);
if (c == NULL) {
if (overlay == true) {
sourcePos.error("Resource %s appears in overlay but not"
" in the base package.\n", String8(entry).string());
if (overlay == true && mCanAddEntries.indexOf(entry) < 0) {
sourcePos.error("Resource at %s appears in overlay but not"
" in the base package; use <add-resource> to add.\n",
String8(entry).string());
return NULL;
}
c = new ConfigList(entry, sourcePos);

View File

@@ -132,6 +132,9 @@ public:
const String16& name,
const String16& comment);
void canAddEntry(const SourcePos& pos,
const String16& package, const String16& type, const String16& name);
size_t size() const;
size_t numLocalResources() const;
bool hasResources() const;
@@ -413,7 +416,9 @@ public:
status_t addPublic(const SourcePos& pos,
const String16& name,
const uint32_t ident);
void canAddEntry(const String16& name);
String16 getName() const { return mName; }
sp<Entry> getEntry(const String16& entry,
const SourcePos& pos,
@@ -435,6 +440,8 @@ public:
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;
@@ -443,6 +450,7 @@ public:
SortedVector<ConfigDescription> mUniqueConfigs;
DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
Vector<sp<ConfigList> > mOrderedConfigs;
SortedVector<String16> mCanAddEntries;
int32_t mPublicIndex;
int32_t mIndex;
SourcePos mPos;