summaryrefslogtreecommitdiff
path: root/tools/aapt/ResourceTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt/ResourceTable.cpp')
-rw-r--r--tools/aapt/ResourceTable.cpp251
1 files changed, 118 insertions, 133 deletions
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index ac5463864366..cf1d4fd33a78 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1713,12 +1713,49 @@ status_t compileResourceFile(Bundle* bundle,
return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}
-ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
- : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
- mIsAppPackage(!bundle->getExtending()), mIsSharedLibrary(bundle->getBuildSharedLibrary()),
- mNumLocal(0),
- mBundle(bundle)
-{
+ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type)
+ : mAssetsPackage(assetsPackage)
+ , mPackageType(type)
+ , mTypeIdOffset(0)
+ , mNumLocal(0)
+ , mBundle(bundle)
+{
+ ssize_t packageId = -1;
+ switch (mPackageType) {
+ case App:
+ case AppFeature:
+ packageId = 0x7f;
+ break;
+
+ case System:
+ packageId = 0x01;
+ break;
+
+ case SharedLibrary:
+ packageId = 0x00;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ sp<Package> package = new Package(mAssetsPackage, packageId);
+ mPackages.add(assetsPackage, package);
+ mOrderedPackages.add(package);
+
+ // Every resource table always has one first entry, the bag attributes.
+ const SourcePos unknown(String8("????"), 0);
+ getType(mAssetsPackage, String16("attr"), unknown);
+}
+
+static uint32_t findLargestTypeIdForPackage(const ResTable& table, const String16& packageName) {
+ const size_t basePackageCount = table.getBasePackageCount();
+ for (size_t i = 0; i < basePackageCount; i++) {
+ if (packageName == table.getBasePackageName(i)) {
+ return table.getLastTypeIdForPackage(i);
+ }
+ }
+ return 0;
}
status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
@@ -1728,59 +1765,22 @@ status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets
return err;
}
- // For future reference to included resources.
mAssets = assets;
-
- const ResTable& incl = assets->getIncludedResources();
-
- // Retrieve all the packages.
- const size_t N = incl.getBasePackageCount();
- for (size_t phase=0; phase<2; phase++) {
- for (size_t i=0; i<N; i++) {
- const String16 name = incl.getBasePackageName(i);
- uint32_t id = incl.getBasePackageId(i);
-
- // First time through: only add base packages (id
- // is not 0); second time through add the other
- // packages.
- if (phase != 0) {
- if (id != 0) {
- // Skip base packages -- already one.
- id = 0;
- } else {
- // Assign a dynamic id.
- id = mNextPackageId;
- }
- } else if (id != 0) {
- if (id == 127) {
- if (mHaveAppPackage) {
- fprintf(stderr, "Included resources have two application packages!\n");
- return UNKNOWN_ERROR;
- }
- mHaveAppPackage = true;
- }
- if (mNextPackageId > id) {
- fprintf(stderr, "Included base package ID %d already in use!\n", id);
- return UNKNOWN_ERROR;
- }
- }
- if (id != 0) {
- NOISY(fprintf(stderr, "Including package %s with ID=%d\n",
- String8(name).string(), id));
- sp<Package> p = new Package(name, id);
- mPackages.add(name, p);
- mOrderedPackages.add(p);
-
- if (id >= mNextPackageId) {
- mNextPackageId = id+1;
- }
- }
+ mTypeIdOffset = findLargestTypeIdForPackage(assets->getIncludedResources(), mAssetsPackage);
+
+ const String8& featureAfter = bundle->getFeatureAfterPackage();
+ if (!featureAfter.isEmpty()) {
+ AssetManager featureAssetManager;
+ if (!featureAssetManager.addAssetPath(featureAfter, NULL)) {
+ fprintf(stderr, "ERROR: Feature package '%s' not found.\n",
+ featureAfter.string());
+ return UNKNOWN_ERROR;
}
- }
- // Every resource table always has one first entry, the bag attributes.
- const SourcePos unknown(String8("????"), 0);
- sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);
+ const ResTable& featureTable = featureAssetManager.getResources(false);
+ mTypeIdOffset = max(mTypeIdOffset,
+ findLargestTypeIdForPackage(featureTable, mAssetsPackage));
+ }
return NO_ERROR;
}
@@ -1820,24 +1820,16 @@ status_t ResourceTable::addEntry(const SourcePos& sourcePos,
const int32_t format,
const bool overwrite)
{
- // Check for adding entries in other packages... for now we do
- // nothing. We need to do the right thing here to support skinning.
uint32_t rid = mAssets->getIncludedResources()
.identifierForName(name.string(), name.size(),
type.string(), type.size(),
package.string(), package.size());
if (rid != 0) {
- return NO_ERROR;
+ sourcePos.error("Resource entry %s/%s is already defined in package %s.",
+ String8(type).string(), String8(name).string(), String8(package).string());
+ return UNKNOWN_ERROR;
}
-#if 0
- if (name == String16("left")) {
- printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
- sourcePos.file.string(), sourcePos.line, String8(type).string(),
- String8(value).string());
- }
-#endif
-
sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
params, doSetIndex);
if (e == NULL) {
@@ -1868,15 +1860,11 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos,
type.string(), type.size(),
package.string(), package.size());
if (rid != 0) {
- return NO_ERROR;
- }
-
-#if 0
- if (name == String16("left")) {
- printf("Adding bag left: file=%s, line=%d, type=%s\n",
- sourcePos.file.striing(), sourcePos.line, String8(type).string());
+ sourcePos.error("Resource entry %s/%s is already defined in package %s.",
+ String8(type).string(), String8(name).string(), String8(package).string());
+ return UNKNOWN_ERROR;
}
-#endif
+
if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {
bool canAdd = false;
sp<Package> p = mPackages.valueFor(package);
@@ -2117,9 +2105,6 @@ uint32_t ResourceTable::getResId(const String16& package,
uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);
if (id != 0) return id; // cache hit
- sp<Package> p = mPackages.valueFor(package);
- if (p == NULL) return 0;
-
// First look for this in the included resources...
uint32_t specFlags = 0;
uint32_t rid = mAssets->getIncludedResources()
@@ -2134,13 +2119,11 @@ uint32_t ResourceTable::getResId(const String16& package,
}
}
- if (Res_INTERNALID(rid)) {
- return ResourceIdCache::store(package, type, name, onlyPublic, rid);
- }
- return ResourceIdCache::store(package, type, name, onlyPublic,
- Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid)));
+ return ResourceIdCache::store(package, type, name, onlyPublic, rid);
}
+ sp<Package> p = mPackages.valueFor(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);
@@ -2294,9 +2277,12 @@ uint32_t ResourceTable::getCustomResourceWithCreation(
}
if (mAssetsPackage != package) {
- mCurrentXmlPos.warning("creating resource for external package %s: %s/%s.",
+ mCurrentXmlPos.error("creating resource for external package %s: %s/%s.",
String8(package).string(), String8(type).string(), String8(name).string());
- mCurrentXmlPos.printf("This will be an error in a future version of AAPT.");
+ if (package == String16("android")) {
+ mCurrentXmlPos.printf("did you mean to use @+id instead of @+android:id?");
+ }
+ return 0;
}
String16 value("false");
@@ -2479,6 +2465,7 @@ status_t ResourceTable::assignResourceIds()
continue;
}
+ // 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) {
firstError = err;
@@ -2512,6 +2499,11 @@ status_t ResourceTable::assignResourceIds()
}
}
+ uint32_t typeIdOffset = 0;
+ if (mPackageType == AppFeature && p->getName() == mAssetsPackage) {
+ typeIdOffset = mTypeIdOffset;
+ }
+
const SourcePos unknown(String8("????"), 0);
sp<Type> attr = p->getType(String16("attr"), unknown);
@@ -2527,7 +2519,7 @@ status_t ResourceTable::assignResourceIds()
}
const size_t N = t->getOrderedConfigs().size();
- t->setIndex(ti+1);
+ t->setIndex(ti + 1 + typeIdOffset);
LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
"First type is not attr!");
@@ -2599,7 +2591,7 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
if (rid == 0) {
return UNKNOWN_ERROR;
}
- if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
+ if (Res_GETPACKAGE(rid) + 1 == p->getAssignedId()) {
typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
String16 comment(c->getComment());
@@ -2608,11 +2600,6 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
// String8(c->getName()).string(), String8(comment).string());
comment = c->getTypeComment();
typeSymbols->appendTypeComment(String8(c->getName()), comment);
- } else {
-#if 0
- printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
- Res_GETPACKAGE(rid), p->getAssignedId());
-#endif
}
}
}
@@ -2749,7 +2736,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>&
}
continue;
} else if (p->getAssignedId() == 0x00) {
- if (!bundle->getBuildSharedLibrary()) {
+ if (mPackageType != SharedLibrary) {
fprintf(stderr, "ERROR: Package %s can not have ID=0x00 unless building a shared library.",
String8(p->getName()).string());
return UNKNOWN_ERROR;
@@ -2761,15 +2748,24 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>&
StringPool typeStrings(useUTF8);
StringPool keyStrings(useUTF8);
+ ssize_t stringsAdded = 0;
const size_t N = p->getOrderedTypes().size();
for (size_t ti=0; ti<N; ti++) {
sp<Type> t = p->getOrderedTypes().itemAt(ti);
if (t == NULL) {
typeStrings.add(String16("<empty>"), false);
+ stringsAdded++;
continue;
}
+
+ while (stringsAdded < t->getIndex() - 1) {
+ typeStrings.add(String16("<empty>"), false);
+ stringsAdded++;
+ }
+
const String16 typeName(t->getName());
typeStrings.add(typeName, false);
+ stringsAdded++;
// This is a hack to tweak the sorting order of the final strings,
// to put stuff that is generally not language-specific first.
@@ -2862,7 +2858,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>&
memset(header, 0, sizeof(*header));
header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
header->header.headerSize = htods(sizeof(*header));
- header->id = htodl(p->getAssignedId());
+ header->id = htodl(static_cast<uint32_t>(p->getAssignedId()));
strcpy16_htod(header->name, p->getName().string());
// Write the string blocks.
@@ -2902,7 +2898,9 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>&
LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
"Type name %s not found",
String8(typeName).string());
-
+ if (t == NULL) {
+ continue;
+ }
const bool filterable = (typeName != mipmap16);
const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
@@ -3062,21 +3060,25 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>&
tHeader->header.size = htodl(data->getSize()-typeStart);
}
- bool missing_entry = false;
- const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ?
- "error" : "warning";
- 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));
- missing_entry = true;
+ // If we're building splits, then each invocation of the flattening
+ // step will have 'missing' entries. Don't warn/error for this case.
+ if (bundle->getSplitConfigurations().isEmpty()) {
+ bool missing_entry = false;
+ const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ?
+ "error" : "warning";
+ 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));
+ missing_entry = true;
+ }
+ }
+ if (bundle->getErrorOnMissingConfigEntry() && missing_entry) {
+ fprintf(stderr, "Error: Missing entries, quit!\n");
+ return NOT_ENOUGH_DATA;
}
- }
- if (bundle->getErrorOnMissingConfigEntry() && missing_entry) {
- fprintf(stderr, "Error: Missing entries, quit!\n");
- return NOT_ENOUGH_DATA;
}
}
@@ -3819,8 +3821,8 @@ status_t ResourceTable::Type::applyPublicEntryOrder()
return hasError ? UNKNOWN_ERROR : NO_ERROR;
}
-ResourceTable::Package::Package(const String16& name, ssize_t includedId)
- : mName(name), mIncludedId(includedId),
+ResourceTable::Package::Package(const String16& name, size_t packageId)
+ : mName(name), mPackageId(packageId),
mTypeStringsMapping(0xffffffff),
mKeyStringsMapping(0xffffffff)
{
@@ -3945,26 +3947,10 @@ status_t ResourceTable::Package::applyPublicTypeOrder()
sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
{
- sp<Package> p = mPackages.valueFor(package);
- if (p == NULL) {
- if (mIsAppPackage) {
- if (mHaveAppPackage) {
- fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
- "Use -x to create extended resources.\n");
- return NULL;
- }
- mHaveAppPackage = true;
- p = new Package(package, mIsSharedLibrary ? 0 : 127);
- } else {
- p = new Package(package, mNextPackageId);
- }
- //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
- // String8(package).string(), p->getAssignedId());
- mPackages.add(package, p);
- mOrderedPackages.add(p);
- mNextPackageId++;
+ if (package != mAssetsPackage) {
+ return NULL;
}
- return p;
+ return mPackages.valueFor(package);
}
sp<ResourceTable::Type> ResourceTable::getType(const String16& package,
@@ -3997,11 +3983,10 @@ sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
const ResTable_config* config) const
{
- int pid = Res_GETPACKAGE(resID)+1;
+ size_t pid = Res_GETPACKAGE(resID)+1;
const size_t N = mOrderedPackages.size();
- size_t i;
sp<Package> p;
- for (i=0; i<N; i++) {
+ for (size_t i = 0; i < N; i++) {
sp<Package> check = mOrderedPackages[i];
if (check->getAssignedId() == pid) {
p = check;