Revert "Implement AAPT Bundle format"

This reverts commit 9d0f7d44d5.

Caused a build breakage when parsing some attributes.

Change-Id: I89ca958b2f2e820d353648df8aadd90bbe8d8339
This commit is contained in:
Adam Lesinski
2015-11-30 21:07:44 +00:00
parent 9d0f7d44d5
commit 5b9847ca3f
5 changed files with 5 additions and 271 deletions

View File

@@ -1537,14 +1537,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();
while (!workQueue.empty()) {
CompileResourceWorkItem& workItem = workQueue.front();
if (workItem.xmlRoot != NULL) {
err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.xmlRoot,
workItem.file, &table, xmlFlags);
} else {
err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file,
&table, xmlFlags);
}
err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file, &table, xmlFlags);
if (err == NO_ERROR) {
assets->addResource(workItem.resPath.getPathLeaf(),
workItem.resPath,

View File

@@ -88,11 +88,8 @@ status_t compileXmlFile(const Bundle* bundle,
root->setUTF8(true);
}
if (table->processBundleFormat(bundle, resourceName, target, root) != NO_ERROR) {
return UNKNOWN_ERROR;
}
bool hasErrors = false;
if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
status_t err = root->assignResourceIds(assets, table);
if (err != NO_ERROR) {
@@ -4758,9 +4755,9 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
newConfig.sdkVersion = sdkVersionToGenerate;
sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
AaptGroupEntry(newConfig), target->getResourceType());
String8 resPath = String8::format("res/%s/%s.xml",
String8 resPath = String8::format("res/%s/%s",
newFile->getGroupEntry().toDirName(target->getResourceType()).string(),
String8(resourceName).string());
target->getSourceFile().getPathLeaf().string());
resPath.convertToResPath();
// Add a resource table entry.
@@ -4787,7 +4784,6 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
item.resourceName = resourceName;
item.resPath = resPath;
item.file = newFile;
item.xmlRoot = newRoot;
mWorkQueue.push(item);
}
@@ -4829,226 +4825,3 @@ void ResourceTable::getDensityVaryingResources(
}
}
}
static String16 buildNamespace(const String16& package) {
return String16("http://schemas.android.com/apk/res/") + package;
}
static sp<XMLNode> findOnlyChildElement(const sp<XMLNode>& parent) {
const Vector<sp<XMLNode> >& children = parent->getChildren();
sp<XMLNode> onlyChild;
for (size_t i = 0; i < children.size(); i++) {
if (children[i]->getType() != XMLNode::TYPE_CDATA) {
if (onlyChild != NULL) {
return NULL;
}
onlyChild = children[i];
}
}
return onlyChild;
}
/**
* Detects use of the `bundle' format and extracts nested resources into their own top level
* resources. The bundle format looks like this:
*
* <!-- res/drawable/bundle.xml -->
* <animated-vector xmlns:aapt="http://schemas.android.com/aapt">
* <aapt:attr name="android:drawable">
* <vector android:width="60dp"
* android:height="60dp">
* <path android:name="v"
* android:fillColor="#000000"
* android:pathData="M300,70 l 0,-70 70,..." />
* </vector>
* </aapt:attr>
* </animated-vector>
*
* When AAPT sees the <aapt:attr> tag, it will extract its single element and its children
* into a new high-level resource, assigning it a name and ID. Then value of the `name`
* attribute must be a resource attribute. That resource attribute is inserted into the parent
* with the reference to the extracted resource as the value.
*
* <!-- res/drawable/bundle.xml -->
* <animated-vector android:drawable="@drawable/bundle_1.xml">
* </animated-vector>
*
* <!-- res/drawable/bundle_1.xml -->
* <vector android:width="60dp"
* android:height="60dp">
* <path android:name="v"
* android:fillColor="#000000"
* android:pathData="M300,70 l 0,-70 70,..." />
* </vector>
*/
status_t ResourceTable::processBundleFormat(const Bundle* bundle,
const String16& resourceName,
const sp<AaptFile>& target,
const sp<XMLNode>& root) {
Vector<sp<XMLNode> > namespaces;
if (root->getType() == XMLNode::TYPE_NAMESPACE) {
namespaces.push(root);
}
return processBundleFormatImpl(bundle, resourceName, target, root, &namespaces);
}
status_t ResourceTable::processBundleFormatImpl(const Bundle* bundle,
const String16& resourceName,
const sp<AaptFile>& target,
const sp<XMLNode>& parent,
Vector<sp<XMLNode> >* namespaces) {
const String16 kAaptNamespaceUri16("http://schemas.android.com/aapt");
const String16 kName16("name");
const String16 kAttr16("attr");
const String16 kAssetPackage16(mAssets->getPackage());
Vector<sp<XMLNode> >& children = parent->getChildren();
for (size_t i = 0; i < children.size(); i++) {
const sp<XMLNode>& child = children[i];
if (child->getType() == XMLNode::TYPE_CDATA) {
continue;
} else if (child->getType() == XMLNode::TYPE_NAMESPACE) {
namespaces->push(child);
}
if (child->getElementNamespace() != kAaptNamespaceUri16 ||
child->getElementName() != kAttr16) {
status_t result = processBundleFormatImpl(bundle, resourceName, target, child,
namespaces);
if (result != NO_ERROR) {
return result;
}
if (child->getType() == XMLNode::TYPE_NAMESPACE) {
namespaces->pop();
}
continue;
}
// This is the <aapt:attr> tag. Look for the 'name' attribute.
SourcePos source(child->getFilename(), child->getStartLineNumber());
sp<XMLNode> nestedRoot = findOnlyChildElement(child);
if (nestedRoot == NULL) {
source.error("<%s:%s> must have exactly one child element",
String8(child->getElementNamespace()).string(),
String8(child->getElementName()).string());
return UNKNOWN_ERROR;
}
// Find the special attribute 'parent-attr'. This attribute's value contains
// the resource attribute for which this element should be assigned in the parent.
const XMLNode::attribute_entry* attr = child->getAttribute(String16(), kName16);
if (attr == NULL) {
source.error("inline resource definition must specify an attribute via 'name'");
return UNKNOWN_ERROR;
}
// Parse the attribute name.
const char* errorMsg = NULL;
String16 attrPackage, attrType, attrName;
bool result = ResTable::expandResourceRef(attr->string.string(),
attr->string.size(),
&attrPackage, &attrType, &attrName,
&kAttr16, &kAssetPackage16,
&errorMsg, NULL);
if (!result) {
source.error("invalid attribute name for 'name': %s", errorMsg);
return UNKNOWN_ERROR;
}
if (attrType != kAttr16) {
// The value of the 'name' attribute must be an attribute reference.
source.error("value of 'name' must be an attribute reference.");
return UNKNOWN_ERROR;
}
// Generate a name for this nested resource and try to add it to the table.
// We do this in a loop because the name may be taken, in which case we will
// increment a suffix until we succeed.
String8 nestedResourceName;
String8 nestedResourcePath;
int suffix = 1;
while (true) {
// This child element will be extracted into its own resource file.
// Generate a name and path for it from its parent.
nestedResourceName = String8::format("%s_%d",
String8(resourceName).string(), suffix++);
nestedResourcePath = String8::format("res/%s/%s.xml",
target->getGroupEntry().toDirName(target->getResourceType())
.string(),
nestedResourceName.string());
// Lookup or create the entry for this name.
sp<Entry> entry = getEntry(kAssetPackage16,
String16(target->getResourceType()),
String16(nestedResourceName),
source,
false,
&target->getGroupEntry().toParams(),
true);
if (entry == NULL) {
return UNKNOWN_ERROR;
}
if (entry->getType() == Entry::TYPE_UNKNOWN) {
// The value for this resource has never been set,
// meaning we're good!
entry->setItem(source, String16(nestedResourcePath));
break;
}
// We failed (name already exists), so try with a different name
// (increment the suffix).
}
if (bundle->getVerbose()) {
source.printf("generating nested resource %s:%s/%s",
mAssets->getPackage().string(), target->getResourceType().string(),
nestedResourceName.string());
}
// Build the attribute reference and assign it to the parent.
String16 nestedResourceRef = String16(String8::format("@%s:%s/%s",
mAssets->getPackage().string(), target->getResourceType().string(),
nestedResourceName.string()));
String16 attrNs = buildNamespace(attrPackage);
if (parent->getAttribute(attrNs, attrName) != NULL) {
SourcePos(parent->getFilename(), parent->getStartLineNumber())
.error("parent of nested resource already defines attribute '%s:%s'",
String8(attrPackage).string(), String8(attrName).string());
return UNKNOWN_ERROR;
}
// Add the reference to the inline resource.
parent->addAttribute(attrNs, attrName, nestedResourceRef);
// Remove the <aapt:attr> child element from here.
children.removeAt(i);
i--;
// Append all namespace declarations that we've seen on this branch in the XML tree
// to this resource.
// We do this because the order of namespace declarations and prefix usage is determined
// by the developer and we do not want to override any decisions. Be conservative.
for (size_t nsIndex = namespaces->size(); nsIndex > 0; nsIndex--) {
const sp<XMLNode>& ns = namespaces->itemAt(nsIndex - 1);
sp<XMLNode> newNs = XMLNode::newNamespace(ns->getFilename(), ns->getNamespacePrefix(),
ns->getNamespaceUri());
newNs->addChild(nestedRoot);
nestedRoot = newNs;
}
// Schedule compilation of the nested resource.
CompileResourceWorkItem workItem;
workItem.resPath = nestedResourcePath;
workItem.resourceName = String16(nestedResourceName);
workItem.xmlRoot = nestedRoot;
workItem.file = new AaptFile(target->getSourceFile(), target->getGroupEntry(),
target->getResourceType());
mWorkQueue.push(workItem);
}
return NO_ERROR;
}

View File

@@ -83,7 +83,6 @@ struct CompileResourceWorkItem {
String16 resourceName;
String8 resPath;
sp<AaptFile> file;
sp<XMLNode> xmlRoot;
};
class ResourceTable : public ResTable::Accessor
@@ -207,12 +206,6 @@ public:
const sp<AaptFile>& file,
const sp<XMLNode>& root);
status_t processBundleFormat(const Bundle* bundle,
const String16& resourceName,
const sp<AaptFile>& file,
const sp<XMLNode>& parent);
sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
const bool isBase);
@@ -593,11 +586,6 @@ private:
Res_value* outValue);
int getPublicAttributeSdkLevel(uint32_t attrId) const;
status_t processBundleFormatImpl(const Bundle* bundle,
const String16& resourceName,
const sp<AaptFile>& file,
const sp<XMLNode>& parent,
Vector<sp<XMLNode> >* namespaces);
String16 mAssetsPackage;
PackageType mPackageType;

View File

@@ -693,12 +693,6 @@ const Vector<sp<XMLNode> >& XMLNode::getChildren() const
return mChildren;
}
Vector<sp<XMLNode> >& XMLNode::getChildren()
{
return mChildren;
}
const String8& XMLNode::getFilename() const
{
return mFilename;
@@ -723,18 +717,6 @@ const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns,
return NULL;
}
bool XMLNode::removeAttribute(const String16& ns, const String16& name)
{
for (size_t i = 0; i < mAttributes.size(); i++) {
const attribute_entry& ae(mAttributes.itemAt(i));
if (ae.ns == ns && ae.name == name) {
removeAttribute(i);
return true;
}
}
return false;
}
XMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns,
const String16& name)
{

View File

@@ -55,7 +55,7 @@ public:
sp<XMLNode> newCData(const String8& filename) {
return new XMLNode(filename);
}
enum type {
TYPE_NAMESPACE,
TYPE_ELEMENT,
@@ -70,7 +70,6 @@ public:
const String16& getElementNamespace() const;
const String16& getElementName() const;
const Vector<sp<XMLNode> >& getChildren() const;
Vector<sp<XMLNode> >& getChildren();
const String8& getFilename() const;
@@ -98,7 +97,6 @@ public:
const Vector<attribute_entry>& getAttributes() const;
const attribute_entry* getAttribute(const String16& ns, const String16& name) const;
bool removeAttribute(const String16& ns, const String16& name);
attribute_entry* editAttribute(const String16& ns, const String16& name);