am d4e5b601: am 37e3df38: am 1aa4db07: am 81745c51: Merge "AAPT: Continuation of public/private attribute fix" into lmp-dev
* commit 'd4e5b601c7da5c662d8cf9c46177810fdeeed23f': AAPT: Continuation of public/private attribute fix
This commit is contained in:
@@ -104,6 +104,9 @@ private:
|
||||
struct AaptGroupEntry
|
||||
{
|
||||
public:
|
||||
AaptGroupEntry() {}
|
||||
AaptGroupEntry(const ConfigDescription& config) : mParams(config) {}
|
||||
|
||||
bool initFromDirName(const char* dir, String8* resType);
|
||||
|
||||
inline const ConfigDescription& toParams() const { return mParams; }
|
||||
|
||||
@@ -1483,7 +1483,7 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t postProcessImage(const sp<AaptAssets>& assets,
|
||||
status_t postProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
|
||||
ResourceTable* table, const sp<AaptFile>& file)
|
||||
{
|
||||
String8 ext(file->getPath().getPathExtension());
|
||||
@@ -1491,7 +1491,8 @@ status_t postProcessImage(const sp<AaptAssets>& assets,
|
||||
// At this point, now that we have all the resource data, all we need to
|
||||
// do is compile XML files.
|
||||
if (strcmp(ext.string(), ".xml") == 0) {
|
||||
return compileXmlFile(assets, file, table);
|
||||
String16 resourceName(parseResourceName(file->getPath().getPathLeaf()));
|
||||
return compileXmlFile(bundle, assets, resourceName, file, table);
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
|
||||
@@ -20,7 +20,7 @@ status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
|
||||
|
||||
status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest);
|
||||
|
||||
status_t postProcessImage(const sp<AaptAssets>& assets,
|
||||
status_t postProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
|
||||
ResourceTable* table, const sp<AaptFile>& file);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,4 +62,7 @@ int dumpResources(Bundle* bundle);
|
||||
|
||||
status_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets,
|
||||
FILE* fp, bool includeRaw);
|
||||
|
||||
android::String8 parseResourceName(const String8& pathLeaf);
|
||||
|
||||
#endif // __MAIN_H
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
// ==========================================================================
|
||||
// ==========================================================================
|
||||
|
||||
static String8 parseResourceName(const String8& leaf)
|
||||
String8 parseResourceName(const String8& leaf)
|
||||
{
|
||||
const char* firstDot = strchr(leaf.string(), '.');
|
||||
const char* str = leaf.string();
|
||||
@@ -1088,7 +1088,7 @@ status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& a
|
||||
manifest->addChild(app);
|
||||
root->addChild(manifest);
|
||||
|
||||
int err = compileXmlFile(assets, root, outFile, table);
|
||||
int err = compileXmlFile(bundle, assets, String16(), root, outFile, table);
|
||||
if (err < NO_ERROR) {
|
||||
return err;
|
||||
}
|
||||
@@ -1336,7 +1336,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
ResourceDirIterator it(layouts, String8("layout"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
String8 src = it.getFile()->getPrintableSource();
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err == NO_ERROR) {
|
||||
ResXMLTree block;
|
||||
block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
|
||||
@@ -1355,7 +1356,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (anims != NULL) {
|
||||
ResourceDirIterator it(anims, String8("anim"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1370,7 +1372,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (animators != NULL) {
|
||||
ResourceDirIterator it(animators, String8("animator"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1385,7 +1388,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (interpolators != NULL) {
|
||||
ResourceDirIterator it(interpolators, String8("interpolator"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1400,7 +1404,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (transitions != NULL) {
|
||||
ResourceDirIterator it(transitions, String8("transition"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1415,7 +1420,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (xmls != NULL) {
|
||||
ResourceDirIterator it(xmls, String8("xml"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1430,7 +1436,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (drawables != NULL) {
|
||||
ResourceDirIterator it(drawables, String8("drawable"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = postProcessImage(assets, &table, it.getFile());
|
||||
err = postProcessImage(bundle, assets, &table, it.getFile());
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1445,7 +1451,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (colors != NULL) {
|
||||
ResourceDirIterator it(colors, String8("color"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err != NO_ERROR) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1461,7 +1468,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
ResourceDirIterator it(menus, String8("menu"));
|
||||
while ((err=it.next()) == NO_ERROR) {
|
||||
String8 src = it.getFile()->getPrintableSource();
|
||||
err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
|
||||
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
|
||||
it.getFile(), &table, xmlFlags);
|
||||
if (err == NO_ERROR) {
|
||||
ResXMLTree block;
|
||||
block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
|
||||
@@ -1477,6 +1485,22 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
err = NO_ERROR;
|
||||
}
|
||||
|
||||
// Now compile any generated resources.
|
||||
std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();
|
||||
while (!workQueue.empty()) {
|
||||
CompileResourceWorkItem& workItem = workQueue.front();
|
||||
err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file, &table, xmlFlags);
|
||||
if (err == NO_ERROR) {
|
||||
assets->addResource(workItem.resPath.getPathLeaf(),
|
||||
workItem.resPath,
|
||||
workItem.file,
|
||||
workItem.file->getResourceType());
|
||||
} else {
|
||||
hasErrors = true;
|
||||
}
|
||||
workQueue.pop();
|
||||
}
|
||||
|
||||
if (table.validateLocalizations()) {
|
||||
hasErrors = true;
|
||||
}
|
||||
@@ -1509,7 +1533,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
if (err < NO_ERROR) {
|
||||
return err;
|
||||
}
|
||||
err = compileXmlFile(assets, manifestTree, manifestFile, &table);
|
||||
err = compileXmlFile(bundle, assets, String16(), manifestTree, manifestFile, &table);
|
||||
if (err < NO_ERROR) {
|
||||
return err;
|
||||
}
|
||||
@@ -1599,7 +1623,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
||||
sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(),
|
||||
manifestFile->getGroupEntry(),
|
||||
manifestFile->getResourceType());
|
||||
err = compileXmlFile(assets, manifestFile,
|
||||
err = compileXmlFile(bundle, assets, String16(), manifestFile,
|
||||
outManifestFile, &table,
|
||||
XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
|
||||
| XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES);
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
#define NOISY(x) //x
|
||||
|
||||
status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
status_t compileXmlFile(const Bundle* bundle,
|
||||
const sp<AaptAssets>& assets,
|
||||
const String16& resourceName,
|
||||
const sp<AaptFile>& target,
|
||||
ResourceTable* table,
|
||||
int options)
|
||||
@@ -27,10 +29,12 @@ status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
return compileXmlFile(assets, root, target, table, options);
|
||||
return compileXmlFile(bundle, assets, resourceName, root, target, table, options);
|
||||
}
|
||||
|
||||
status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
status_t compileXmlFile(const Bundle* bundle,
|
||||
const sp<AaptAssets>& assets,
|
||||
const String16& resourceName,
|
||||
const sp<AaptFile>& target,
|
||||
const sp<AaptFile>& outTarget,
|
||||
ResourceTable* table,
|
||||
@@ -41,10 +45,12 @@ status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
return compileXmlFile(assets, root, outTarget, table, options);
|
||||
return compileXmlFile(bundle, assets, resourceName, root, outTarget, table, options);
|
||||
}
|
||||
|
||||
status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
status_t compileXmlFile(const Bundle* bundle,
|
||||
const sp<AaptAssets>& assets,
|
||||
const String16& resourceName,
|
||||
const sp<XMLNode>& root,
|
||||
const sp<AaptFile>& target,
|
||||
ResourceTable* table,
|
||||
@@ -77,6 +83,10 @@ status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
if (hasErrors) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
NOISY(printf("Input XML Resource:\n"));
|
||||
NOISY(root->print());
|
||||
@@ -4028,6 +4038,39 @@ sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
|
||||
return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());
|
||||
}
|
||||
|
||||
sp<ResourceTable::ConfigList> ResourceTable::getConfigList(const String16& package,
|
||||
const String16& type, const String16& name) const
|
||||
{
|
||||
const size_t packageCount = mOrderedPackages.size();
|
||||
for (size_t pi = 0; pi < packageCount; pi++) {
|
||||
const sp<Package>& p = mOrderedPackages[pi];
|
||||
if (p == NULL || p->getName() != package) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Vector<sp<Type> >& types = p->getOrderedTypes();
|
||||
const size_t typeCount = types.size();
|
||||
for (size_t ti = 0; ti < typeCount; ti++) {
|
||||
const sp<Type>& t = types[ti];
|
||||
if (t == NULL || t->getName() != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Vector<sp<ConfigList> >& configs = t->getOrderedConfigs();
|
||||
const size_t configCount = configs.size();
|
||||
for (size_t ci = 0; ci < configCount; ci++) {
|
||||
const sp<ConfigList>& cl = configs[ci];
|
||||
if (cl == NULL || cl->getName() != name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
|
||||
const ResTable_config* config) const
|
||||
{
|
||||
@@ -4157,6 +4200,22 @@ bool ResourceTable::isAttributeFromL(uint32_t attrId) {
|
||||
(attrId & 0x0000ffff) >= (baseAttrId & 0x0000ffff);
|
||||
}
|
||||
|
||||
static bool isMinSdkVersionLOrAbove(const Bundle* bundle) {
|
||||
if (bundle->getMinSdkVersion() != NULL && strlen(bundle->getMinSdkVersion()) > 0) {
|
||||
const char firstChar = bundle->getMinSdkVersion()[0];
|
||||
if (firstChar >= 'L' && firstChar <= 'Z') {
|
||||
// L is the code-name for the v21 release.
|
||||
return true;
|
||||
}
|
||||
|
||||
const int minSdk = atoi(bundle->getMinSdkVersion());
|
||||
if (minSdk >= SDK_L) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the entries in the resource table to account for compatibility
|
||||
* issues with older versions of Android.
|
||||
@@ -4200,19 +4259,10 @@ bool ResourceTable::isAttributeFromL(uint32_t attrId) {
|
||||
* attribute will be respected.
|
||||
*/
|
||||
status_t ResourceTable::modifyForCompat(const Bundle* bundle) {
|
||||
if (bundle->getMinSdkVersion() != NULL) {
|
||||
if (isMinSdkVersionLOrAbove(bundle)) {
|
||||
// If this app will only ever run on L+ devices,
|
||||
// we don't need to do any compatibility work.
|
||||
|
||||
if (String8("L") == bundle->getMinSdkVersion()) {
|
||||
// Code-name for the v21 release.
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
const int minSdk = atoi(bundle->getMinSdkVersion());
|
||||
if (minSdk >= SDK_L) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
const String16 attr16("attr");
|
||||
@@ -4309,3 +4359,104 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) {
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t ResourceTable::modifyForCompat(const Bundle* bundle,
|
||||
const String16& resourceName,
|
||||
const sp<AaptFile>& target,
|
||||
const sp<XMLNode>& root) {
|
||||
if (isMinSdkVersionLOrAbove(bundle)) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
if (target->getResourceType() == "" || target->getGroupEntry().toParams().sdkVersion >= SDK_L) {
|
||||
// Skip resources that have no type (AndroidManifest.xml) or are already version qualified with v21
|
||||
// or higher.
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
Vector<key_value_pair_t<sp<XMLNode>, size_t> > attrsToRemove;
|
||||
|
||||
Vector<sp<XMLNode> > nodesToVisit;
|
||||
nodesToVisit.push(root);
|
||||
while (!nodesToVisit.isEmpty()) {
|
||||
sp<XMLNode> node = nodesToVisit.top();
|
||||
nodesToVisit.pop();
|
||||
|
||||
const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes();
|
||||
const size_t attrCount = attrs.size();
|
||||
for (size_t i = 0; i < attrCount; i++) {
|
||||
const XMLNode::attribute_entry& attr = attrs[i];
|
||||
if (isAttributeFromL(attr.nameResId)) {
|
||||
attrsToRemove.add(key_value_pair_t<sp<XMLNode>, size_t>(node, i));
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule a visit to the children.
|
||||
const Vector<sp<XMLNode> >& children = node->getChildren();
|
||||
const size_t childCount = children.size();
|
||||
for (size_t i = 0; i < childCount; i++) {
|
||||
nodesToVisit.push(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (attrsToRemove.isEmpty()) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
ConfigDescription newConfig(target->getGroupEntry().toParams());
|
||||
newConfig.sdkVersion = SDK_L;
|
||||
|
||||
// Look to see if we already have an overriding v21 configuration.
|
||||
sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),
|
||||
String16(target->getResourceType()), resourceName);
|
||||
if (cl->getEntries().indexOfKey(newConfig) < 0) {
|
||||
// We don't have an overriding entry for v21, so we must duplicate this one.
|
||||
sp<XMLNode> newRoot = root->clone();
|
||||
sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
|
||||
AaptGroupEntry(newConfig), target->getResourceType());
|
||||
String8 resPath = String8::format("res/%s/%s",
|
||||
newFile->getGroupEntry().toDirName(target->getResourceType()).string(),
|
||||
target->getPath().getPathLeaf().string());
|
||||
resPath.convertToResPath();
|
||||
|
||||
// Add a resource table entry.
|
||||
SourcePos(target->getSourceFile(), -1).printf(
|
||||
"using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.",
|
||||
SDK_L,
|
||||
mAssets->getPackage().string(),
|
||||
newFile->getResourceType().string(),
|
||||
String8(resourceName).string(),
|
||||
newConfig.toString().string());
|
||||
|
||||
addEntry(SourcePos(),
|
||||
String16(mAssets->getPackage()),
|
||||
String16(target->getResourceType()),
|
||||
resourceName,
|
||||
String16(resPath),
|
||||
NULL,
|
||||
&newConfig);
|
||||
|
||||
// Schedule this to be compiled.
|
||||
CompileResourceWorkItem item;
|
||||
item.resourceName = resourceName;
|
||||
item.resPath = resPath;
|
||||
item.file = newFile;
|
||||
mWorkQueue.push(item);
|
||||
}
|
||||
|
||||
const size_t removeCount = attrsToRemove.size();
|
||||
for (size_t i = 0; i < removeCount; i++) {
|
||||
sp<XMLNode> node = attrsToRemove[i].key;
|
||||
size_t attrIndex = attrsToRemove[i].value;
|
||||
const XMLNode::attribute_entry& ae = node->getAttributes()[attrIndex];
|
||||
SourcePos(node->getFilename(), node->getStartLineNumber()).printf(
|
||||
"removing attribute %s%s%s from <%s>",
|
||||
String8(ae.ns).string(),
|
||||
(ae.ns.size() == 0 ? "" : ":"),
|
||||
String8(ae.name).string(),
|
||||
String8(node->getElementName()).string());
|
||||
node->removeAttribute(attrIndex);
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
#include "SourcePos.h"
|
||||
#include "ResourceFilter.h"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -33,18 +34,24 @@ enum {
|
||||
| XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
|
||||
};
|
||||
|
||||
status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
status_t compileXmlFile(const Bundle* bundle,
|
||||
const sp<AaptAssets>& assets,
|
||||
const String16& resourceName,
|
||||
const sp<AaptFile>& target,
|
||||
ResourceTable* table,
|
||||
int options = XML_COMPILE_STANDARD_RESOURCE);
|
||||
|
||||
status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
status_t compileXmlFile(const Bundle* bundle,
|
||||
const sp<AaptAssets>& assets,
|
||||
const String16& resourceName,
|
||||
const sp<AaptFile>& target,
|
||||
const sp<AaptFile>& outTarget,
|
||||
ResourceTable* table,
|
||||
int options = XML_COMPILE_STANDARD_RESOURCE);
|
||||
|
||||
status_t compileXmlFile(const sp<AaptAssets>& assets,
|
||||
status_t compileXmlFile(const Bundle* bundle,
|
||||
const sp<AaptAssets>& assets,
|
||||
const String16& resourceName,
|
||||
const sp<XMLNode>& xmlTree,
|
||||
const sp<AaptFile>& target,
|
||||
ResourceTable* table,
|
||||
@@ -71,6 +78,14 @@ struct AccessorCookie
|
||||
}
|
||||
};
|
||||
|
||||
// Holds the necessary information to compile the
|
||||
// resource.
|
||||
struct CompileResourceWorkItem {
|
||||
String16 resourceName;
|
||||
String8 resPath;
|
||||
sp<AaptFile> file;
|
||||
};
|
||||
|
||||
class ResourceTable : public ResTable::Accessor
|
||||
{
|
||||
public:
|
||||
@@ -92,6 +107,18 @@ public:
|
||||
return mAssetsPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the queue of resources that need to be compiled.
|
||||
* This is only used for resources that have been generated
|
||||
* during the compilation phase. If they were just added
|
||||
* to the AaptAssets, then they may be skipped over
|
||||
* and would mess up iteration order for the existing
|
||||
* resources.
|
||||
*/
|
||||
queue<CompileResourceWorkItem>& getWorkQueue() {
|
||||
return mWorkQueue;
|
||||
}
|
||||
|
||||
status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
|
||||
|
||||
status_t addPublic(const SourcePos& pos,
|
||||
@@ -166,6 +193,10 @@ public:
|
||||
bool hasResources() const;
|
||||
|
||||
status_t modifyForCompat(const Bundle* bundle);
|
||||
status_t modifyForCompat(const Bundle* bundle,
|
||||
const String16& resourceName,
|
||||
const sp<AaptFile>& file,
|
||||
const sp<XMLNode>& root);
|
||||
|
||||
sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
|
||||
const bool isBase);
|
||||
@@ -527,6 +558,9 @@ private:
|
||||
bool doSetIndex = false);
|
||||
sp<const Entry> getEntry(uint32_t resID,
|
||||
const ResTable_config* config = NULL) const;
|
||||
sp<ConfigList> getConfigList(const String16& package,
|
||||
const String16& type,
|
||||
const String16& name) const;
|
||||
const Item* getItem(uint32_t resID, uint32_t attrID) const;
|
||||
bool getItemValue(uint32_t resID, uint32_t attrID,
|
||||
Res_value* outValue);
|
||||
@@ -545,6 +579,7 @@ private:
|
||||
|
||||
// key = string resource name, value = set of locales in which that name is defined
|
||||
map<String16, map<String8, SourcePos> > mLocalizations;
|
||||
queue<CompileResourceWorkItem> mWorkQueue;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -621,6 +621,12 @@ sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)
|
||||
return state.root;
|
||||
}
|
||||
|
||||
XMLNode::XMLNode()
|
||||
: mNextAttributeIndex(0x80000000)
|
||||
, mStartLineNumber(0)
|
||||
, mEndLineNumber(0)
|
||||
, mUTF8(false) {}
|
||||
|
||||
XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace)
|
||||
: mNextAttributeIndex(0x80000000)
|
||||
, mFilename(filename)
|
||||
@@ -810,6 +816,32 @@ status_t XMLNode::addAttribute(const String16& ns, const String16& name,
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t XMLNode::removeAttribute(size_t index)
|
||||
{
|
||||
if (getType() == TYPE_CDATA) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
if (index >= mAttributes.size()) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
const attribute_entry& e = mAttributes[index];
|
||||
const uint32_t key = e.nameResId ? e.nameResId : e.index;
|
||||
mAttributeOrder.removeItem(key);
|
||||
mAttributes.removeAt(index);
|
||||
|
||||
// Shift all the indices.
|
||||
const size_t attrCount = mAttributeOrder.size();
|
||||
for (size_t i = 0; i < attrCount; i++) {
|
||||
size_t attrIdx = mAttributeOrder[i];
|
||||
if (attrIdx > index) {
|
||||
mAttributeOrder.replaceValueAt(i, attrIdx - 1);
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId)
|
||||
{
|
||||
attribute_entry& e = mAttributes.editItemAt(attrIdx);
|
||||
@@ -999,6 +1031,30 @@ status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,
|
||||
return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
|
||||
}
|
||||
|
||||
sp<XMLNode> XMLNode::clone() const {
|
||||
sp<XMLNode> copy = new XMLNode();
|
||||
copy->mNamespacePrefix = mNamespacePrefix;
|
||||
copy->mNamespaceUri = mNamespaceUri;
|
||||
copy->mElementName = mElementName;
|
||||
|
||||
const size_t childCount = mChildren.size();
|
||||
for (size_t i = 0; i < childCount; i++) {
|
||||
copy->mChildren.add(mChildren[i]->clone());
|
||||
}
|
||||
|
||||
copy->mAttributes = mAttributes;
|
||||
copy->mAttributeOrder = mAttributeOrder;
|
||||
copy->mNextAttributeIndex = mNextAttributeIndex;
|
||||
copy->mChars = mChars;
|
||||
memcpy(©->mCharsValue, &mCharsValue, sizeof(mCharsValue));
|
||||
copy->mComment = mComment;
|
||||
copy->mFilename = mFilename;
|
||||
copy->mStartLineNumber = mStartLineNumber;
|
||||
copy->mEndLineNumber = mEndLineNumber;
|
||||
copy->mUTF8 = mUTF8;
|
||||
return copy;
|
||||
}
|
||||
|
||||
status_t XMLNode::flatten(const sp<AaptFile>& dest,
|
||||
bool stripComments, bool stripRawValues) const
|
||||
{
|
||||
|
||||
@@ -116,6 +116,8 @@ public:
|
||||
status_t addAttribute(const String16& ns, const String16& name,
|
||||
const String16& value);
|
||||
|
||||
status_t removeAttribute(size_t index);
|
||||
|
||||
void setAttributeResID(size_t attrIdx, uint32_t resId);
|
||||
|
||||
status_t appendChars(const String16& chars);
|
||||
@@ -137,6 +139,8 @@ public:
|
||||
status_t flatten(const sp<AaptFile>& dest, bool stripComments,
|
||||
bool stripRawValues) const;
|
||||
|
||||
sp<XMLNode> clone() const;
|
||||
|
||||
void print(int indent=0);
|
||||
|
||||
private:
|
||||
@@ -163,6 +167,9 @@ private:
|
||||
static void XMLCALL
|
||||
commentData(void *userData, const char *comment);
|
||||
|
||||
// For cloning
|
||||
XMLNode();
|
||||
|
||||
// Creating an element node.
|
||||
XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user