Merge change 21159
* changes: Allow overlays to add resources.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user