diff options
Diffstat (limited to 'tools')
94 files changed, 2126 insertions, 2071 deletions
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 899d26818548..b94d14fd4b75 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -219,7 +219,7 @@ bool AaptLocaleValue::initFromFilterString(const String8& str) { if (numTags >= 1) { const String8& lang = parts[0]; if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) { - setLanguage(lang.string()); + setLanguage(lang.c_str()); valid = true; } } @@ -232,11 +232,11 @@ bool AaptLocaleValue::initFromFilterString(const String8& str) { const String8& part2 = parts[1]; if ((part2.length() == 2 && isAlpha(part2)) || (part2.length() == 3 && isNumber(part2))) { - setRegion(part2.string()); + setRegion(part2.c_str()); } else if (part2.length() == 4 && isAlpha(part2)) { - setScript(part2.string()); + setScript(part2.c_str()); } else if (part2.length() >= 4 && part2.length() <= 8) { - setVariant(part2.string()); + setVariant(part2.c_str()); } else { valid = false; } @@ -249,9 +249,9 @@ bool AaptLocaleValue::initFromFilterString(const String8& str) { const String8& part3 = parts[2]; if (((part3.length() == 2 && isAlpha(part3)) || (part3.length() == 3 && isNumber(part3))) && script[0]) { - setRegion(part3.string()); + setRegion(part3.c_str()); } else if (part3.length() >= 4 && part3.length() <= 8) { - setVariant(part3.string()); + setVariant(part3.c_str()); } else { valid = false; } @@ -262,7 +262,7 @@ bool AaptLocaleValue::initFromFilterString(const String8& str) { const String8& part4 = parts[3]; if (part4.length() >= 4 && part4.length() <= 8) { - setVariant(part4.string()); + setVariant(part4.c_str()); } else { valid = false; } @@ -310,7 +310,7 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta break; default: fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", - part.string()); + part.c_str()); return -1; } } else if (subtags.size() == 3) { @@ -324,7 +324,7 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta } else if (subtags[1].size() == 2 || subtags[1].size() == 3) { setRegion(subtags[1]); } else { - fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.string()); + fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.c_str()); return -1; } @@ -341,14 +341,14 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta setRegion(subtags[2]); setVariant(subtags[3]); } else { - fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.string()); + fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.c_str()); return -1; } return ++currentIndex; } else { if ((part.length() == 2 || part.length() == 3) - && isAlpha(part) && strcmp("car", part.string())) { + && isAlpha(part) && strcmp("car", part.c_str())) { setLanguage(part); if (++currentIndex == size) { return size; @@ -358,8 +358,8 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta } part = parts[currentIndex]; - if (part.string()[0] == 'r' && part.length() == 3) { - setRegion(part.string() + 1); + if (part.c_str()[0] == 'r' && part.length() == 3) { + setRegion(part.c_str() + 1); if (++currentIndex == size) { return size; } @@ -524,8 +524,8 @@ status_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplic ssize_t index = mFiles.indexOfKey(file->getGroupEntry()); if (index >= 0 && overwriteDuplicate) { fprintf(stderr, "warning: overwriting '%s' with '%s'\n", - mFiles[index]->getSourceFile().string(), - file->getSourceFile().string()); + mFiles[index]->getSourceFile().c_str(), + file->getSourceFile().c_str()); removeFile(index); index = -1; } @@ -545,7 +545,7 @@ status_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplic const sp<AaptFile>& originalFile = mFiles.valueAt(index); SourcePos(file->getSourceFile(), -1) .error("Duplicate file.\n%s: Original is here. %s", - originalFile->getPrintableSource().string(), + originalFile->getPrintableSource().c_str(), (withoutVersion.version != 0) ? "The version qualifier may be implied." : ""); return UNKNOWN_ERROR; } @@ -557,21 +557,21 @@ void AaptGroup::removeFile(size_t index) void AaptGroup::print(const String8& prefix) const { - printf("%s%s\n", prefix.string(), getPath().string()); + printf("%s%s\n", prefix.c_str(), getPath().c_str()); const size_t N=mFiles.size(); size_t i; for (i=0; i<N; i++) { sp<AaptFile> file = mFiles.valueAt(i); const AaptGroupEntry& e = file->getGroupEntry(); if (file->hasData()) { - printf("%s Gen: (%s) %d bytes\n", prefix.string(), e.toDirName(String8()).string(), + printf("%s Gen: (%s) %d bytes\n", prefix.c_str(), e.toDirName(String8()).c_str(), (int)file->getSize()); } else { - printf("%s Src: (%s) %s\n", prefix.string(), e.toDirName(String8()).string(), - file->getPrintableSource().string()); + printf("%s Src: (%s) %s\n", prefix.c_str(), e.toDirName(String8()).c_str(), + file->getPrintableSource().c_str()); } - //printf("%s File Group Entry: %s\n", prefix.string(), - // file->getGroupEntry().toDirName(String8()).string()); + //printf("%s File Group Entry: %s\n", prefix.c_str(), + // file->getGroupEntry().toDirName(String8()).c_str()); } } @@ -660,9 +660,9 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, { DIR* dir = NULL; - dir = opendir(srcDir.string()); + dir = opendir(srcDir.c_str()); if (dir == NULL) { - fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); + fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.c_str(), strerror(errno)); return UNKNOWN_ERROR; } @@ -676,7 +676,7 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, if (entry == NULL) break; - if (isHidden(srcDir.string(), entry->d_name)) + if (isHidden(srcDir.c_str(), entry->d_name)) continue; String8 name(entry->d_name); @@ -701,8 +701,8 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, String8 pathName(srcDir); FileType type; - pathName.appendPath(fileNames[i].string()); - type = getFileType(pathName.string()); + pathName.appendPath(fileNames[i].c_str()); + type = getFileType(pathName.c_str()); if (type == kFileTypeDirectory) { sp<AaptDir> subdir; bool notAdded = false; @@ -732,7 +732,7 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, } else { if (bundle->getVerbose()) - printf(" (ignoring non-file/dir '%s')\n", pathName.string()); + printf(" (ignoring non-file/dir '%s')\n", pathName.c_str()); } } @@ -745,7 +745,7 @@ status_t AaptDir::validate() const const size_t ND = mDirs.size(); size_t i; for (i = 0; i < NF; i++) { - if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) { + if (!validateFileName(mFiles.valueAt(i)->getLeaf().c_str())) { SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( "Invalid filename. Unable to add."); return UNKNOWN_ERROR; @@ -753,11 +753,11 @@ status_t AaptDir::validate() const size_t j; for (j = i+1; j < NF; j++) { - if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), - mFiles.valueAt(j)->getLeaf().string()) == 0) { + if (strcasecmp(mFiles.valueAt(i)->getLeaf().c_str(), + mFiles.valueAt(j)->getLeaf().c_str()) == 0) { SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( "File is case-insensitive equivalent to: %s", - mFiles.valueAt(j)->getPrintableSource().string()); + mFiles.valueAt(j)->getPrintableSource().c_str()); return UNKNOWN_ERROR; } @@ -766,18 +766,18 @@ status_t AaptDir::validate() const } for (j = 0; j < ND; j++) { - if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), - mDirs.valueAt(j)->getLeaf().string()) == 0) { + if (strcasecmp(mFiles.valueAt(i)->getLeaf().c_str(), + mDirs.valueAt(j)->getLeaf().c_str()) == 0) { SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( "File conflicts with dir from: %s", - mDirs.valueAt(j)->getPrintableSource().string()); + mDirs.valueAt(j)->getPrintableSource().c_str()); return UNKNOWN_ERROR; } } } for (i = 0; i < ND; i++) { - if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) { + if (!validateFileName(mDirs.valueAt(i)->getLeaf().c_str())) { SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( "Invalid directory name, unable to add."); return UNKNOWN_ERROR; @@ -785,11 +785,11 @@ status_t AaptDir::validate() const size_t j; for (j = i+1; j < ND; j++) { - if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(), - mDirs.valueAt(j)->getLeaf().string()) == 0) { + if (strcasecmp(mDirs.valueAt(i)->getLeaf().c_str(), + mDirs.valueAt(j)->getLeaf().c_str()) == 0) { SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( "Directory is case-insensitive equivalent to: %s", - mDirs.valueAt(j)->getPrintableSource().string()); + mDirs.valueAt(j)->getPrintableSource().c_str()); return UNKNOWN_ERROR; } } @@ -846,12 +846,12 @@ status_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols) const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i); ssize_t pos = mSymbols.indexOfKey(name); if (pos < 0) { - entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.string()); + entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.c_str()); err = UNKNOWN_ERROR; continue; } //printf("**** setting symbol #%d/%d %s to isJavaSymbol=%d\n", - // i, N, name.string(), entry.isJavaSymbol ? 1 : 0); + // i, N, name.c_str(), entry.isJavaSymbol ? 1 : 0); mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol; } @@ -862,11 +862,11 @@ status_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols) ssize_t pos = mNestedSymbols.indexOfKey(name); if (pos < 0) { SourcePos pos; - pos.error("Java symbol dir %s not defined\n", name.string()); + pos.error("Java symbol dir %s not defined\n", name.c_str()); err = UNKNOWN_ERROR; continue; } - //printf("**** applying java symbols in dir %s\n", name.string()); + //printf("**** applying java symbols in dir %s\n", name.c_str()); status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols); if (myerr != NO_ERROR) { err = myerr; @@ -1131,9 +1131,9 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) { ssize_t err = 0; - DIR* dir = opendir(srcDir.string()); + DIR* dir = opendir(srcDir.c_str()); if (dir == NULL) { - fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); + fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.c_str(), strerror(errno)); return UNKNOWN_ERROR; } @@ -1149,7 +1149,7 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) break; } - if (isHidden(srcDir.string(), entry->d_name)) { + if (isHidden(srcDir.c_str(), entry->d_name)) { continue; } @@ -1160,7 +1160,7 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) String8 resType; bool b = group.initFromDirName(entry->d_name, &resType); if (!b) { - fprintf(stderr, "invalid resource directory name: %s %s\n", srcDir.string(), + fprintf(stderr, "invalid resource directory name: %s %s\n", srcDir.c_str(), entry->d_name); err = -1; continue; @@ -1168,7 +1168,7 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) { int maxResInt = atoi(bundle->getMaxResVersion()); - const char *verString = group.getVersionString().string(); + const char *verString = group.getVersionString().c_str(); int dirVersionInt = atoi(verString + 1); // skip 'v' in version name if (dirVersionInt > maxResInt) { fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name); @@ -1176,7 +1176,7 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) } } - FileType type = getFileType(subdirName.string()); + FileType type = getFileType(subdirName.c_str()); if (type == kFileTypeDirectory) { sp<AaptDir> dir = makeDir(resType); @@ -1200,7 +1200,7 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) } } else { if (bundle->getVerbose()) { - fprintf(stderr, " (ignoring file '%s')\n", subdirName.string()); + fprintf(stderr, " (ignoring file '%s')\n", subdirName.c_str()); } } } @@ -1248,7 +1248,7 @@ AaptAssets::slurpResourceZip(Bundle* /* bundle */, const char* filename) String8 remain; if (entryName.walkPath(&remain) == kResourceDir) { // these are the resources, pull their type out of the directory name - kind.initFromDirName(remain.walkPath().string(), &resType); + kind.initFromDirName(remain.walkPath().c_str(), &resType); } else { // these are untyped and don't have an AaptGroupEntry } @@ -1263,7 +1263,7 @@ AaptAssets::slurpResourceZip(Bundle* /* bundle */, const char* filename) sp<AaptFile> file = new AaptFile(entryName, kind, resType); status_t err = dir->addLeafFile(entryName.getPathLeaf(), file); if (err != NO_ERROR) { - fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string()); + fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.c_str()); count = err; goto bail; } @@ -1273,7 +1273,7 @@ AaptAssets::slurpResourceZip(Bundle* /* bundle */, const char* filename) if (entryName == "AndroidManifest.xml") { printf("AndroidManifest.xml\n"); } - printf("\n\nfile: %s\n", entryName.string()); + printf("\n\nfile: %s\n", entryName.c_str()); #endif size_t len = entry->getUncompressedLen(); @@ -1317,9 +1317,9 @@ status_t AaptAssets::filter(Bundle* bundle) uint32_t preferredDensity = 0; if (bundle->getPreferredDensity().size() > 0) { ResTable_config preferredConfig; - if (!AaptConfig::parseDensity(bundle->getPreferredDensity().string(), &preferredConfig)) { + if (!AaptConfig::parseDensity(bundle->getPreferredDensity().c_str(), &preferredConfig)) { fprintf(stderr, "Error parsing preferred density: %s\n", - bundle->getPreferredDensity().string()); + bundle->getPreferredDensity().c_str()); return UNKNOWN_ERROR; } preferredDensity = preferredConfig.density; @@ -1332,11 +1332,11 @@ status_t AaptAssets::filter(Bundle* bundle) if (bundle->getVerbose()) { if (!reqFilter->isEmpty()) { printf("Applying required filter: %s\n", - bundle->getConfigurations().string()); + bundle->getConfigurations().c_str()); } if (preferredDensity > 0) { printf("Applying preferred density filter: %s\n", - bundle->getPreferredDensity().string()); + bundle->getPreferredDensity().c_str()); } } @@ -1385,7 +1385,7 @@ status_t AaptAssets::filter(Bundle* bundle) if (!reqFilter->match(config)) { if (bundle->getVerbose()) { printf("Pruning unneeded resource: %s\n", - file->getPrintableSource().string()); + file->getPrintableSource().c_str()); } grp->removeFile(k); k--; @@ -1453,7 +1453,7 @@ status_t AaptAssets::filter(Bundle* bundle) if (bestDensity != config.density) { if (bundle->getVerbose()) { printf("Pruning unneeded resource: %s\n", - file->getPrintableSource().string()); + file->getPrintableSource().c_str()); } grp->removeFile(k); k--; @@ -1495,10 +1495,10 @@ status_t AaptAssets::applyJavaSymbols() ssize_t pos = mSymbols.indexOfKey(name); if (pos < 0) { SourcePos pos; - pos.error("Java symbol dir %s not defined\n", name.string()); + pos.error("Java symbol dir %s not defined\n", name.c_str()); return UNKNOWN_ERROR; } - //printf("**** applying java symbols in dir %s\n", name.string()); + //printf("**** applying java symbols in dir %s\n", name.c_str()); status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols); if (err != NO_ERROR) { return err; @@ -1510,7 +1510,7 @@ status_t AaptAssets::applyJavaSymbols() bool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const { //printf("isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\n", - // sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0, + // sym.name.c_str(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0, // sym.isJavaSymbol ? 1 : 0); if (!mHavePrivateSymbols) return true; if (sym.isPublic) return true; @@ -1529,12 +1529,12 @@ status_t AaptAssets::buildIncludedResources(Bundle* bundle) const size_t packageIncludeCount = includes.size(); for (size_t i = 0; i < packageIncludeCount; i++) { if (bundle->getVerbose()) { - printf("Including resources from package: %s\n", includes[i].string()); + printf("Including resources from package: %s\n", includes[i].c_str()); } if (!mIncludedAssets.addAssetPath(includes[i], NULL)) { fprintf(stderr, "ERROR: Asset package include '%s' not found.\n", - includes[i].string()); + includes[i].c_str()); return UNKNOWN_ERROR; } } @@ -1543,12 +1543,12 @@ status_t AaptAssets::buildIncludedResources(Bundle* bundle) if (!featureOfBase.isEmpty()) { if (bundle->getVerbose()) { printf("Including base feature resources from package: %s\n", - featureOfBase.string()); + featureOfBase.c_str()); } if (!mIncludedAssets.addAssetPath(featureOfBase, NULL)) { fprintf(stderr, "ERROR: base feature package '%s' not found.\n", - featureOfBase.string()); + featureOfBase.c_str()); return UNKNOWN_ERROR; } } @@ -1581,23 +1581,23 @@ void AaptAssets::print(const String8& prefix) const innerPrefix.append(" "); String8 innerInnerPrefix(innerPrefix); innerInnerPrefix.append(" "); - printf("%sConfigurations:\n", prefix.string()); + printf("%sConfigurations:\n", prefix.c_str()); const size_t N=mGroupEntries.size(); for (size_t i=0; i<N; i++) { String8 cname = mGroupEntries.itemAt(i).toDirName(String8()); - printf("%s %s\n", prefix.string(), - cname != "" ? cname.string() : "(default)"); + printf("%s %s\n", prefix.c_str(), + cname != "" ? cname.c_str() : "(default)"); } - printf("\n%sFiles:\n", prefix.string()); + printf("\n%sFiles:\n", prefix.c_str()); AaptDir::print(innerPrefix); - printf("\n%sResource Dirs:\n", prefix.string()); + printf("\n%sResource Dirs:\n", prefix.c_str()); const Vector<sp<AaptDir> >& resdirs = mResDirs; const size_t NR = resdirs.size(); for (size_t i=0; i<NR; i++) { const sp<AaptDir>& d = resdirs.itemAt(i); - printf("%s Type %s\n", prefix.string(), d->getLeaf().string()); + printf("%s Type %s\n", prefix.c_str(), d->getLeaf().c_str()); d->print(innerInnerPrefix); } } @@ -1631,7 +1631,7 @@ valid_symbol_name(const String8& symbol) NULL }; const char*const* k = KEYWORDS; - const char*const s = symbol.string(); + const char*const s = symbol.c_str(); while (*k) { if (0 == strcmp(s, *k)) { return false; diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index eadd48a6c261..498fc4e38c8c 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -463,7 +463,7 @@ private: if (valid_symbol_name(symbol)) { return true; } - pos.error("invalid %s: '%s'\n", label, symbol.string()); + pos.error("invalid %s: '%s'\n", label, symbol.c_str()); return false; } AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) { diff --git a/tools/aapt/AaptConfig.cpp b/tools/aapt/AaptConfig.cpp index 0aca45ea8d60..7578f79f792e 100644 --- a/tools/aapt/AaptConfig.cpp +++ b/tools/aapt/AaptConfig.cpp @@ -39,7 +39,7 @@ bool parse(const String8& str, ConfigDescription* out) { ssize_t index = 0; ssize_t localeIndex = 0; const ssize_t N = parts.size(); - const char* part = parts[index].string(); + const char* part = parts[index].c_str(); if (str.length() == 0) { goto success; @@ -50,7 +50,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseMnc(part, &config)) { @@ -58,7 +58,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } // Locale spans a few '-' separators, so we let it @@ -72,7 +72,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index >= N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseLayoutDirection(part, &config)) { @@ -80,7 +80,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseSmallestScreenWidthDp(part, &config)) { @@ -88,7 +88,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseScreenWidthDp(part, &config)) { @@ -96,7 +96,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseScreenHeightDp(part, &config)) { @@ -104,7 +104,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseScreenLayoutSize(part, &config)) { @@ -112,7 +112,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseScreenLayoutLong(part, &config)) { @@ -120,7 +120,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseScreenRound(part, &config)) { @@ -128,7 +128,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseWideColorGamut(part, &config)) { @@ -136,7 +136,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseHdr(part, &config)) { @@ -144,7 +144,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseOrientation(part, &config)) { @@ -152,7 +152,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseUiModeType(part, &config)) { @@ -160,7 +160,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseUiModeNight(part, &config)) { @@ -168,7 +168,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseDensity(part, &config)) { @@ -176,7 +176,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseTouchscreen(part, &config)) { @@ -184,7 +184,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseKeysHidden(part, &config)) { @@ -192,7 +192,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseKeyboard(part, &config)) { @@ -200,7 +200,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseNavHidden(part, &config)) { @@ -208,7 +208,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseNavigation(part, &config)) { @@ -216,7 +216,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseScreenSize(part, &config)) { @@ -224,7 +224,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } if (parseVersion(part, &config)) { @@ -232,7 +232,7 @@ bool parse(const String8& str, ConfigDescription* out) { if (index == N) { goto success; } - part = parts[index].string(); + part = parts[index].c_str(); } // Unrecognized. @@ -773,8 +773,8 @@ bool parseScreenSize(const char* name, ResTable_config* out) { if (y == name || *y != 0) return false; String8 yName(x, y-x); - uint16_t w = (uint16_t)atoi(xName.string()); - uint16_t h = (uint16_t)atoi(yName.string()); + uint16_t w = (uint16_t)atoi(xName.c_str()); + uint16_t h = (uint16_t)atoi(yName.c_str()); if (w < h) { return false; } @@ -805,7 +805,7 @@ bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) { String8 xName(name, x-name); if (out) { - out->smallestScreenWidthDp = (uint16_t)atoi(xName.string()); + out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str()); } return true; @@ -827,7 +827,7 @@ bool parseScreenWidthDp(const char* name, ResTable_config* out) { String8 xName(name, x-name); if (out) { - out->screenWidthDp = (uint16_t)atoi(xName.string()); + out->screenWidthDp = (uint16_t)atoi(xName.c_str()); } return true; @@ -849,7 +849,7 @@ bool parseScreenHeightDp(const char* name, ResTable_config* out) { String8 xName(name, x-name); if (out) { - out->screenHeightDp = (uint16_t)atoi(xName.string()); + out->screenHeightDp = (uint16_t)atoi(xName.c_str()); } return true; @@ -875,7 +875,7 @@ bool parseVersion(const char* name, ResTable_config* out) { String8 sdkName(name, s-name); if (out) { - out->sdkVersion = (uint16_t)atoi(sdkName.string()); + out->sdkVersion = (uint16_t)atoi(sdkName.c_str()); out->minorVersion = 0; } diff --git a/tools/aapt/AaptUtil.cpp b/tools/aapt/AaptUtil.cpp index 293e144b71fe..e82860de578a 100644 --- a/tools/aapt/AaptUtil.cpp +++ b/tools/aapt/AaptUtil.cpp @@ -23,7 +23,7 @@ namespace AaptUtil { Vector<String8> split(const String8& str, const char sep) { Vector<String8> parts; - const char* p = str.string(); + const char* p = str.c_str(); const char* q; while (true) { @@ -41,7 +41,7 @@ Vector<String8> split(const String8& str, const char sep) { Vector<String8> splitAndLowerCase(const String8& str, const char sep) { Vector<String8> parts; - const char* p = str.string(); + const char* p = str.c_str(); const char* q; while (true) { diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp index cc10db9e1523..cecd95a5e616 100644 --- a/tools/aapt/Android.bp +++ b/tools/aapt/Android.bp @@ -97,6 +97,7 @@ cc_library_host_static { "ResourceTable.cpp", "SourcePos.cpp", "StringPool.cpp", + "Utils.cpp", "WorkQueue.cpp", "XMLNode.cpp", "ZipEntry.cpp", diff --git a/tools/aapt/ApkBuilder.cpp b/tools/aapt/ApkBuilder.cpp index 01e02e270b63..335c43b96599 100644 --- a/tools/aapt/ApkBuilder.cpp +++ b/tools/aapt/ApkBuilder.cpp @@ -36,7 +36,7 @@ status_t ApkBuilder::createSplitForConfigs(const std::set<ConfigDescription>& co if (splitConfigs.count(*iter) > 0) { // Can't have overlapping configurations. fprintf(stderr, "ERROR: Split configuration '%s' is already defined " - "in another split.\n", iter->toString().string()); + "in another split.\n", iter->toString().c_str()); return ALREADY_EXISTS; } } @@ -115,10 +115,10 @@ status_t ApkSplit::addEntry(const String8& path, const sp<AaptFile>& file) { } void ApkSplit::print() const { - fprintf(stderr, "APK Split '%s'\n", mName.string()); + fprintf(stderr, "APK Split '%s'\n", mName.c_str()); std::set<OutputEntry>::const_iterator iter = mFiles.begin(); for (; iter != mFiles.end(); iter++) { - fprintf(stderr, " %s (%s)\n", iter->getPath().string(), iter->getFile()->getSourceFile().string()); + fprintf(stderr, " %s (%s)\n", iter->getPath().c_str(), iter->getFile()->getSourceFile().c_str()); } } diff --git a/tools/aapt/CacheUpdater.h b/tools/aapt/CacheUpdater.h index 6fa96d67e6a3..2dc143c6a66d 100644 --- a/tools/aapt/CacheUpdater.h +++ b/tools/aapt/CacheUpdater.h @@ -66,7 +66,7 @@ public: // Check optomistically to see if all directories exist. // If something in the path doesn't exist, then walk the path backwards // and find the place to start creating directories forward. - if (stat(path.string(),&s) == -1) { + if (stat(path.c_str(),&s) == -1) { // Walk backwards to find place to start creating directories existsPath = path; do { @@ -74,7 +74,7 @@ public: // the string of paths to create. toCreate = existsPath.getPathLeaf().appendPath(toCreate); existsPath = existsPath.getPathDir(); - } while (stat(existsPath.string(),&s) == -1); + } while (stat(existsPath.c_str(),&s) == -1); // Walk forwards and build directories as we go do { @@ -82,9 +82,9 @@ public: existsPath.appendPath(toCreate.walkPath(&remains)); toCreate = remains; #ifdef _WIN32 - _mkdir(existsPath.string()); + _mkdir(existsPath.c_str()); #else - mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); + mkdir(existsPath.c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); #endif } while (remains.length() > 0); } //if @@ -93,8 +93,8 @@ public: // Delete a file virtual void deleteFile(String8 path) { - if (remove(path.string()) != 0) - fprintf(stderr,"ERROR DELETING %s\n",path.string()); + if (remove(path.c_str()) != 0) + fprintf(stderr,"ERROR DELETING %s\n",path.c_str()); }; // Process an image from source out to dest diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index d02fd83df6af..5a06b102592a 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -240,13 +240,13 @@ static void printResolvedResourceAttribute(const ResTable& resTable, const ResXM } if (value.dataType == Res_value::TYPE_STRING) { String8 result = AaptXml::getResolvedAttribute(resTable, tree, attrRes, outError); - printf("%s='%s'", attrLabel.string(), - ResTable::normalizeForOutput(result.string()).string()); + printf("%s='%s'", attrLabel.c_str(), + ResTable::normalizeForOutput(result.c_str()).c_str()); } else if (Res_value::TYPE_FIRST_INT <= value.dataType && value.dataType <= Res_value::TYPE_LAST_INT) { - printf("%s='%d'", attrLabel.string(), value.data); + printf("%s='%d'", attrLabel.c_str(), value.data); } else { - printf("%s='0x%x'", attrLabel.string(), (int)value.data); + printf("%s='0x%x'", attrLabel.c_str(), (int)value.data); } } @@ -353,23 +353,23 @@ static void printCompatibleScreens(ResXMLTree& tree, String8* outError) { } static void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1, - const String8& requiredFeature = String8::empty(), - const String8& requiredNotFeature = String8::empty()) { - printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); + const String8& requiredFeature = String8(), + const String8& requiredNotFeature = String8()) { + printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.c_str()).c_str()); if (maxSdkVersion != -1) { printf(" maxSdkVersion='%d'", maxSdkVersion); } if (requiredFeature.length() > 0) { - printf(" requiredFeature='%s'", requiredFeature.string()); + printf(" requiredFeature='%s'", requiredFeature.c_str()); } if (requiredNotFeature.length() > 0) { - printf(" requiredNotFeature='%s'", requiredNotFeature.string()); + printf(" requiredNotFeature='%s'", requiredNotFeature.c_str()); } printf("\n"); if (optional) { printf("optional-permission: name='%s'", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); if (maxSdkVersion != -1) { printf(" maxSdkVersion='%d'", maxSdkVersion); } @@ -380,7 +380,7 @@ static void printUsesPermission(const String8& name, bool optional=false, int ma static void printUsesPermissionSdk23(const String8& name, int maxSdkVersion=-1) { printf("uses-permission-sdk-23: "); - printf("name='%s'", ResTable::normalizeForOutput(name.string()).string()); + printf("name='%s'", ResTable::normalizeForOutput(name.c_str()).c_str()); if (maxSdkVersion != -1) { printf(" maxSdkVersion='%d'", maxSdkVersion); } @@ -390,11 +390,11 @@ static void printUsesPermissionSdk23(const String8& name, int maxSdkVersion=-1) static void printUsesImpliedPermission(const String8& name, const String8& reason, const int32_t maxSdkVersion = -1) { printf("uses-implied-permission: name='%s'", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); if (maxSdkVersion != -1) { printf(" maxSdkVersion='%d'", maxSdkVersion); } - printf(" reason='%s'\n", ResTable::normalizeForOutput(reason.string()).string()); + printf(" reason='%s'\n", ResTable::normalizeForOutput(reason.c_str()).c_str()); } Vector<String8> getNfcAidCategories(AssetManager& assets, const String8& xmlPath, bool offHost, @@ -556,7 +556,7 @@ static void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatu static void printFeatureGroupImpl(const FeatureGroup& grp, const KeyedVector<String8, ImpliedFeature>* impliedFeatures) { - printf("feature-group: label='%s'\n", grp.label.string()); + printf("feature-group: label='%s'\n", grp.label.c_str()); if (grp.openGLESVersion > 0) { printf(" uses-gl-es: '0x%x'\n", grp.openGLESVersion); @@ -570,7 +570,7 @@ static void printFeatureGroupImpl(const FeatureGroup& grp, const String8& featureName = grp.features.keyAt(i); printf(" uses-feature%s: name='%s'", (required ? "" : "-not-required"), - ResTable::normalizeForOutput(featureName.string()).string()); + ResTable::normalizeForOutput(featureName.c_str()).c_str()); if (version > 0) { printf(" version='%d'", version); @@ -589,15 +589,15 @@ static void printFeatureGroupImpl(const FeatureGroup& grp, } String8 printableFeatureName(ResTable::normalizeForOutput( - impliedFeature.name.string())); + impliedFeature.name.c_str())); const char* sdk23Suffix = impliedFeature.impliedBySdk23 ? "-sdk-23" : ""; - printf(" uses-feature%s: name='%s'\n", sdk23Suffix, printableFeatureName.string()); + printf(" uses-feature%s: name='%s'\n", sdk23Suffix, printableFeatureName.c_str()); printf(" uses-implied-feature%s: name='%s' reason='", sdk23Suffix, - printableFeatureName.string()); + printableFeatureName.c_str()); const size_t numReasons = impliedFeature.reasons.size(); for (size_t j = 0; j < numReasons; j++) { - printf("%s", impliedFeature.reasons[j].string()); + printf("%s", impliedFeature.reasons[j].c_str()); if (j + 2 < numReasons) { printf(", "); } else if (j + 1 < numReasons) { @@ -649,43 +649,43 @@ static void addImpliedFeaturesForPermission(const int targetSdk, const String8& bool impliedBySdk23Permission) { if (name == "android.permission.CAMERA") { addImpliedFeature(impliedFeatures, "android.hardware.camera", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); } else if (name == "android.permission.ACCESS_FINE_LOCATION") { if (targetSdk < SDK_LOLLIPOP) { addImpliedFeature(impliedFeatures, "android.hardware.location.gps", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); addImpliedFeature(impliedFeatures, "android.hardware.location.gps", String8::format("targetSdkVersion < %d", SDK_LOLLIPOP), impliedBySdk23Permission); } addImpliedFeature(impliedFeatures, "android.hardware.location", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); } else if (name == "android.permission.ACCESS_COARSE_LOCATION") { if (targetSdk < SDK_LOLLIPOP) { addImpliedFeature(impliedFeatures, "android.hardware.location.network", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); addImpliedFeature(impliedFeatures, "android.hardware.location.network", String8::format("targetSdkVersion < %d", SDK_LOLLIPOP), impliedBySdk23Permission); } addImpliedFeature(impliedFeatures, "android.hardware.location", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); } else if (name == "android.permission.ACCESS_MOCK_LOCATION" || name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" || name == "android.permission.INSTALL_LOCATION_PROVIDER") { addImpliedFeature(impliedFeatures, "android.hardware.location", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); } else if (name == "android.permission.BLUETOOTH" || name == "android.permission.BLUETOOTH_ADMIN") { if (targetSdk > SDK_DONUT) { addImpliedFeature(impliedFeatures, "android.hardware.bluetooth", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); addImpliedFeature(impliedFeatures, "android.hardware.bluetooth", String8::format("targetSdkVersion > %d", SDK_DONUT), @@ -693,13 +693,13 @@ static void addImpliedFeaturesForPermission(const int targetSdk, const String8& } } else if (name == "android.permission.RECORD_AUDIO") { addImpliedFeature(impliedFeatures, "android.hardware.microphone", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); } else if (name == "android.permission.ACCESS_WIFI_STATE" || name == "android.permission.CHANGE_WIFI_STATE" || name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") { addImpliedFeature(impliedFeatures, "android.hardware.wifi", - String8::format("requested %s permission", name.string()), + String8::format("requested %s permission", name.c_str()), impliedBySdk23Permission); } else if (name == "android.permission.CALL_PHONE" || name == "android.permission.CALL_PRIVILEGED" || @@ -746,7 +746,7 @@ int doDump(Bundle* bundle) for (size_t i = 0; i < bundle->getPackageIncludes().size(); i++) { const String8& assetPath = bundle->getPackageIncludes()[i]; if (!assets.addAssetPath(assetPath, NULL)) { - fprintf(stderr, "ERROR: included asset path %s could not be loaded\n", assetPath.string()); + fprintf(stderr, "ERROR: included asset path %s could not be loaded\n", assetPath.c_str()); return 1; } } @@ -890,7 +890,7 @@ int doDump(Bundle* bundle) goto bail; } String8 tag(ctag16); - //printf("Depth %d tag %s\n", depth, tag.string()); + //printf("Depth %d tag %s\n", depth, tag.c_str()); if (depth == 1) { if (tag != "manifest") { SourcePos(manifestFile, tree.getLineNumber()).error( @@ -898,14 +898,14 @@ int doDump(Bundle* bundle) goto bail; } String8 pkg = AaptXml::getAttribute(tree, NULL, "package", NULL); - printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); + printf("package: %s\n", ResTable::normalizeForOutput(pkg.c_str()).c_str()); } else if (depth == 2) { if (tag == "permission") { String8 error; String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name': %s", error.string()); + "ERROR getting 'android:name': %s", error.c_str()); goto bail; } @@ -915,13 +915,13 @@ int doDump(Bundle* bundle) goto bail; } printf("permission: %s\n", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); } else if (tag == "uses-permission") { String8 error; String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } @@ -938,7 +938,7 @@ int doDump(Bundle* bundle) String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } @@ -1138,7 +1138,7 @@ int doDump(Bundle* bundle) const size_t N = supportedInput.size(); for (size_t i=0; i<N; i++) { printf("%s", ResTable::normalizeForOutput( - supportedInput[i].string()).string()); + supportedInput[i].c_str()).c_str()); if (i != N - 1) { printf("' '"); } else { @@ -1157,27 +1157,27 @@ int doDump(Bundle* bundle) printf("launchable-activity:"); if (aName.length() > 0) { printf(" name='%s' ", - ResTable::normalizeForOutput(aName.string()).string()); + ResTable::normalizeForOutput(aName.c_str()).c_str()); } printf(" label='%s' icon='%s'\n", - ResTable::normalizeForOutput(activityLabel.string()) - .string(), - ResTable::normalizeForOutput(activityIcon.string()) - .string()); + ResTable::normalizeForOutput(activityLabel.c_str()) + .c_str(), + ResTable::normalizeForOutput(activityIcon.c_str()) + .c_str()); } if (isLeanbackLauncherActivity) { printf("leanback-launchable-activity:"); if (aName.length() > 0) { printf(" name='%s' ", - ResTable::normalizeForOutput(aName.string()).string()); + ResTable::normalizeForOutput(aName.c_str()).c_str()); } printf(" label='%s' icon='%s' banner='%s'\n", - ResTable::normalizeForOutput(activityLabel.string()) - .string(), - ResTable::normalizeForOutput(activityIcon.string()) - .string(), - ResTable::normalizeForOutput(activityBanner.string()) - .string()); + ResTable::normalizeForOutput(activityLabel.c_str()) + .c_str(), + ResTable::normalizeForOutput(activityIcon.c_str()) + .c_str(), + ResTable::normalizeForOutput(activityBanner.c_str()) + .c_str()); } } if (!hasIntentFilter) { @@ -1265,7 +1265,7 @@ int doDump(Bundle* bundle) goto bail; } String8 tag(ctag16); - //printf("Depth %d, %s\n", depth, tag.string()); + //printf("Depth %d, %s\n", depth, tag.c_str()); if (depth == 1) { if (tag != "manifest") { SourcePos(manifestFile, tree.getLineNumber()).error( @@ -1274,13 +1274,13 @@ int doDump(Bundle* bundle) } pkg = AaptXml::getAttribute(tree, NULL, "package", NULL); printf("package: name='%s' ", - ResTable::normalizeForOutput(pkg.string()).string()); + ResTable::normalizeForOutput(pkg.c_str()).c_str()); int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:versionCode' attribute: %s", - error.string()); + error.c_str()); goto bail; } if (versionCode > 0) { @@ -1293,16 +1293,16 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:versionName' attribute: %s", - error.string()); + error.c_str()); goto bail; } printf("versionName='%s'", - ResTable::normalizeForOutput(versionName.string()).string()); + ResTable::normalizeForOutput(versionName.c_str()).c_str()); String8 splitName = AaptXml::getAttribute(tree, NULL, "split"); if (!splitName.isEmpty()) { printf(" split='%s'", ResTable::normalizeForOutput( - splitName.string()).string()); + splitName.c_str()).c_str()); } // For 'platformBuildVersionName', using both string and int type as a fallback @@ -1313,7 +1313,7 @@ int doDump(Bundle* bundle) AaptXml::getIntegerAttribute(tree, NULL, "platformBuildVersionName", 0, NULL); if (platformBuildVersionName != "") { - printf(" platformBuildVersionName='%s'", platformBuildVersionName.string()); + printf(" platformBuildVersionName='%s'", platformBuildVersionName.c_str()); } else if (platformBuildVersionNameInt > 0) { printf(" platformBuildVersionName='%d'", platformBuildVersionNameInt); } @@ -1326,7 +1326,7 @@ int doDump(Bundle* bundle) AaptXml::getIntegerAttribute(tree, NULL, "platformBuildVersionCode", 0, NULL); if (platformBuildVersionCode != "") { - printf(" platformBuildVersionCode='%s'", platformBuildVersionCode.string()); + printf(" platformBuildVersionCode='%s'", platformBuildVersionCode.c_str()); } else if (platformBuildVersionCodeInt > 0) { printf(" platformBuildVersionCode='%d'", platformBuildVersionCodeInt); } @@ -1336,7 +1336,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:compileSdkVersion' attribute: %s", - error.string()); + error.c_str()); goto bail; } if (compileSdkVersion > 0) { @@ -1347,7 +1347,7 @@ int doDump(Bundle* bundle) COMPILE_SDK_VERSION_CODENAME_ATTR, &error); if (compileSdkVersionCodename != "") { printf(" compileSdkVersionCodename='%s'", ResTable::normalizeForOutput( - compileSdkVersionCodename.string()).string()); + compileSdkVersionCodename.c_str()).c_str()); } printf("\n"); @@ -1357,7 +1357,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:installLocation' attribute: %s", - error.string()); + error.c_str()); goto bail; } @@ -1387,7 +1387,7 @@ int doDump(Bundle* bundle) String8 label; const size_t NL = locales.size(); for (size_t i=0; i<NL; i++) { - const char* localeStr = locales[i].string(); + const char* localeStr = locales[i].c_str(); assets.setConfiguration(config, localeStr != NULL ? localeStr : ""); String8 llabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error); @@ -1395,13 +1395,13 @@ int doDump(Bundle* bundle) if (localeStr == NULL || strlen(localeStr) == 0) { label = llabel; printf("application-label:'%s'\n", - ResTable::normalizeForOutput(llabel.string()).string()); + ResTable::normalizeForOutput(llabel.c_str()).c_str()); } else { if (label == "") { label = llabel; } printf("application-label-%s:'%s'\n", localeStr, - ResTable::normalizeForOutput(llabel.string()).string()); + ResTable::normalizeForOutput(llabel.c_str()).c_str()); } } } @@ -1415,7 +1415,7 @@ int doDump(Bundle* bundle) &error); if (icon != "") { printf("application-icon-%d:'%s'\n", densities[i], - ResTable::normalizeForOutput(icon.string()).string()); + ResTable::normalizeForOutput(icon.c_str()).c_str()); } } assets.setConfiguration(config); @@ -1423,7 +1423,7 @@ int doDump(Bundle* bundle) String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:icon' attribute: %s", error.string()); + "ERROR getting 'android:icon' attribute: %s", error.c_str()); goto bail; } int32_t testOnly = AaptXml::getIntegerAttribute(tree, TEST_ONLY_ATTR, 0, @@ -1431,7 +1431,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:testOnly' attribute: %s", - error.string()); + error.c_str()); goto bail; } @@ -1439,15 +1439,15 @@ int doDump(Bundle* bundle) &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:banner' attribute: %s", error.string()); + "ERROR getting 'android:banner' attribute: %s", error.c_str()); goto bail; } printf("application: label='%s' ", - ResTable::normalizeForOutput(label.string()).string()); - printf("icon='%s'", ResTable::normalizeForOutput(icon.string()).string()); + ResTable::normalizeForOutput(label.c_str()).c_str()); + printf("icon='%s'", ResTable::normalizeForOutput(icon.c_str()).c_str()); if (banner != "") { printf(" banner='%s'", - ResTable::normalizeForOutput(banner.string()).string()); + ResTable::normalizeForOutput(banner.c_str()).c_str()); } printf("\n"); if (testOnly != 0) { @@ -1458,7 +1458,7 @@ int doDump(Bundle* bundle) ISGAME_ATTR, 0, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:isGame' attribute: %s", error.string()); + "ERROR getting 'android:isGame' attribute: %s", error.c_str()); goto bail; } if (isGame != 0) { @@ -1470,7 +1470,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:debuggable' attribute: %s", - error.string()); + error.c_str()); goto bail; } if (debuggable != 0) { @@ -1500,12 +1500,12 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:minSdkVersion' attribute: %s", - error.string()); + error.c_str()); goto bail; } if (name == "Donut") targetSdk = SDK_DONUT; printf("sdkVersion:'%s'\n", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); } else if (code != -1) { targetSdk = code; printf("sdkVersion:'%d'\n", code); @@ -1522,7 +1522,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:targetSdkVersion' attribute: %s", - error.string()); + error.c_str()); goto bail; } if (name == "Donut" && targetSdk < SDK_DONUT) { @@ -1532,7 +1532,7 @@ int doDump(Bundle* bundle) targetSdk = SDK_CUR_DEVELOPMENT; } printf("targetSdkVersion:'%s'\n", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); } else if (code != -1) { if (targetSdk < code) { targetSdk = code; @@ -1592,7 +1592,7 @@ int doDump(Bundle* bundle) group.label = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:label' attribute: %s", error.string()); + "ERROR getting 'android:label' attribute: %s", error.c_str()); goto bail; } featureGroups.add(group); @@ -1608,7 +1608,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "failed to read attribute 'android:required': %s", - error.string()); + error.c_str()); goto bail; } @@ -1617,7 +1617,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "failed to read attribute 'android:version': %s", - error.string()); + error.c_str()); goto bail; } @@ -1638,7 +1638,7 @@ int doDump(Bundle* bundle) String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } @@ -1682,7 +1682,7 @@ int doDump(Bundle* bundle) String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } @@ -1701,37 +1701,37 @@ int doDump(Bundle* bundle) String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (name != "" && error == "") { printf("uses-package:'%s'\n", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); } else { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } } else if (tag == "original-package") { String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (name != "" && error == "") { printf("original-package:'%s'\n", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); } else { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } } else if (tag == "supports-gl-texture") { String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (name != "" && error == "") { printf("supports-gl-texture:'%s'\n", - ResTable::normalizeForOutput(name.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str()); } else { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } } else if (tag == "compatible-screens") { printCompatibleScreens(tree, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting compatible screens: %s", error.string()); + "ERROR getting compatible screens: %s", error.c_str()); goto bail; } depth--; @@ -1742,8 +1742,8 @@ int doDump(Bundle* bundle) &error); if (publicKey != "" && error == "") { printf("package-verifier: name='%s' publicKey='%s'\n", - ResTable::normalizeForOutput(name.string()).string(), - ResTable::normalizeForOutput(publicKey.string()).string()); + ResTable::normalizeForOutput(name.c_str()).c_str(), + ResTable::normalizeForOutput(publicKey.c_str()).c_str()); } } } @@ -1769,7 +1769,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute: %s", - error.string()); + error.c_str()); goto bail; } @@ -1778,7 +1778,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:label' attribute: %s", - error.string()); + error.c_str()); goto bail; } @@ -1787,7 +1787,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:icon' attribute: %s", - error.string()); + error.c_str()); goto bail; } @@ -1796,7 +1796,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:banner' attribute: %s", - error.string()); + error.c_str()); goto bail; } @@ -1824,14 +1824,14 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute for uses-library" - " %s", error.string()); + " %s", error.c_str()); goto bail; } int req = AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1); printf("uses-library%s:'%s'\n", req ? "" : "-not-required", ResTable::normalizeForOutput( - libraryName.string()).string()); + libraryName.c_str()).c_str()); } else if (tag == "receiver") { withinReceiver = true; receiverName = AaptXml::getAttribute(tree, NAME_ATTR, &error); @@ -1839,7 +1839,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute for receiver:" - " %s", error.string()); + " %s", error.c_str()); goto bail; } @@ -1853,7 +1853,7 @@ int doDump(Bundle* bundle) SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:permission' attribute for" " receiver '%s': %s", - receiverName.string(), error.string()); + receiverName.c_str(), error.c_str()); } } else if (tag == "service") { withinService = true; @@ -1862,7 +1862,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute for " - "service:%s", error.string()); + "service:%s", error.c_str()); goto bail; } @@ -1887,7 +1887,7 @@ int doDump(Bundle* bundle) } else { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:permission' attribute for " - "service '%s': %s", serviceName.string(), error.string()); + "service '%s': %s", serviceName.c_str(), error.c_str()); } } else if (tag == "provider") { withinProvider = true; @@ -1897,7 +1897,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:exported' attribute for provider:" - " %s", error.string()); + " %s", error.c_str()); goto bail; } @@ -1906,7 +1906,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:grantUriPermissions' attribute for " - "provider: %s", error.string()); + "provider: %s", error.c_str()); goto bail; } @@ -1915,7 +1915,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:permission' attribute for " - "provider: %s", error.string()); + "provider: %s", error.c_str()); goto bail; } @@ -1928,11 +1928,11 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute for " - "meta-data: %s", error.string()); + "meta-data: %s", error.c_str()); goto bail; } printf("meta-data: name='%s' ", - ResTable::normalizeForOutput(metaDataName.string()).string()); + ResTable::normalizeForOutput(metaDataName.c_str()).c_str()); printResolvedResourceAttribute(res, tree, VALUE_ATTR, String8("value"), &error); if (error != "") { @@ -1944,7 +1944,7 @@ int doDump(Bundle* bundle) SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:value' or " "'android:resource' attribute for " - "meta-data: %s", error.string()); + "meta-data: %s", error.c_str()); goto bail; } } @@ -1956,7 +1956,7 @@ int doDump(Bundle* bundle) } else { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute: %s", - error.string()); + error.c_str()); goto bail; } } @@ -1969,13 +1969,13 @@ int doDump(Bundle* bundle) Feature feature(true); int32_t featureVers = AaptXml::getIntegerAttribute( - tree, androidSchema.string(), "version", 0, &error); + tree, androidSchema.c_str(), "version", 0, &error); if (error == "") { feature.version = featureVers; } else { SourcePos(manifestFile, tree.getLineNumber()).error( "failed to read attribute 'android:version': %s", - error.string()); + error.c_str()); goto bail; } @@ -2016,8 +2016,8 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:name' attribute for " - "meta-data tag in service '%s': %s", serviceName.string(), - error.string()); + "meta-data tag in service '%s': %s", serviceName.c_str(), + error.c_str()); goto bail; } @@ -2034,7 +2034,7 @@ int doDump(Bundle* bundle) SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting 'android:resource' attribute for " "meta-data tag in service '%s': %s", - serviceName.string(), error.string()); + serviceName.c_str(), error.c_str()); goto bail; } @@ -2043,7 +2043,7 @@ int doDump(Bundle* bundle) if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( "ERROR getting AID category for service '%s'", - serviceName.string()); + serviceName.c_str()); goto bail; } @@ -2064,7 +2064,7 @@ int doDump(Bundle* bundle) action = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'android:name' attribute: %s", error.string()); + "ERROR getting 'android:name' attribute: %s", error.c_str()); goto bail; } @@ -2120,7 +2120,7 @@ int doDump(Bundle* bundle) String8 category = AaptXml::getAttribute(tree, NAME_ATTR, &error); if (error != "") { SourcePos(manifestFile, tree.getLineNumber()).error( - "ERROR getting 'name' attribute: %s", error.string()); + "ERROR getting 'name' attribute: %s", error.c_str()); goto bail; } if (withinActivity) { @@ -2352,7 +2352,7 @@ int doDump(Bundle* bundle) printf("locales:"); const size_t NL = locales.size(); for (size_t i=0; i<NL; i++) { - const char* localeStr = locales[i].string(); + const char* localeStr = locales[i].c_str(); if (localeStr == NULL || strlen(localeStr) == 0) { localeStr = "--_--"; } @@ -2373,7 +2373,7 @@ int doDump(Bundle* bundle) SortedVector<String8> architectures; for (size_t i=0; i<dir->getFileCount(); i++) { architectures.add(ResTable::normalizeForOutput( - dir->getFileName(i).string())); + dir->getFileName(i).c_str())); } bool outputAltNativeCode = false; @@ -2401,7 +2401,7 @@ int doDump(Bundle* bundle) } if (index >= 0) { - printf("native-code: '%s'\n", architectures[index].string()); + printf("native-code: '%s'\n", architectures[index].c_str()); architectures.removeAt(index); outputAltNativeCode = true; } @@ -2414,7 +2414,7 @@ int doDump(Bundle* bundle) } printf("native-code:"); for (size_t i = 0; i < archCount; i++) { - printf(" '%s'", architectures[i].string()); + printf(" '%s'", architectures[i].c_str()); } printf("\n"); } @@ -2428,7 +2428,7 @@ int doDump(Bundle* bundle) res.getConfigurations(&configs); const size_t N = configs.size(); for (size_t i=0; i<N; i++) { - printf("%s\n", configs[i].toString().string()); + printf("%s\n", configs[i].toString().c_str()); } } else { fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); @@ -2486,15 +2486,15 @@ int doAdd(Bundle* bundle) for (int i = 1; i < bundle->getFileSpecCount(); i++) { const char* fileName = bundle->getFileSpecEntry(i); - if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { + if (strcasecmp(String8(fileName).getPathExtension().c_str(), ".gz") == 0) { printf(" '%s'... (from gzip)\n", fileName); - result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); + result = zip->addGzip(fileName, String8(fileName).getBasePath().c_str(), NULL); } else { if (bundle->getJunkPath()) { String8 storageName = String8(fileName).getPathLeaf(); printf(" '%s' as '%s'...\n", fileName, - ResTable::normalizeForOutput(storageName.string()).string()); - result = zip->add(fileName, storageName.string(), + ResTable::normalizeForOutput(storageName.c_str()).c_str()); + result = zip->add(fileName, storageName.c_str(), bundle->getCompressionMethod(), NULL); } else { printf(" '%s'...\n", fileName); @@ -2581,7 +2581,7 @@ static status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilde for (size_t i = 0; i < numDirs; i++) { bool ignore = ignoreConfig; const sp<AaptDir>& subDir = dir->getDirs().valueAt(i); - const char* dirStr = subDir->getLeaf().string(); + const char* dirStr = subDir->getLeaf().c_str(); if (!ignore && strstr(dirStr, "mipmap") == dirStr) { ignore = true; } @@ -2604,7 +2604,7 @@ static status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilde } if (err != NO_ERROR) { fprintf(stderr, "Failed to add %s (%s) to builder.\n", - gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string()); + gp->getPath().c_str(), gp->getFiles()[j]->getPrintableSource().c_str()); return err; } } @@ -2620,13 +2620,13 @@ static String8 buildApkName(const String8& original, const sp<ApkSplit>& split) String8 ext(original.getPathExtension()); if (ext == String8(".apk")) { return String8::format("%s_%s%s", - original.getBasePath().string(), - split->getDirectorySafeName().string(), - ext.string()); + original.getBasePath().c_str(), + split->getDirectorySafeName().c_str(), + ext.c_str()); } - return String8::format("%s_%s", original.string(), - split->getDirectorySafeName().string()); + return String8::format("%s_%s", original.c_str(), + split->getDirectorySafeName().c_str()); } /* @@ -2712,7 +2712,7 @@ int doPackage(Bundle* bundle) for (size_t i = 0; i < numSplits; i++) { std::set<ConfigDescription> configs; if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) { - fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].string()); + fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].c_str()); goto bail; } @@ -2835,7 +2835,7 @@ int doPackage(Bundle* bundle) String8 outputPath = buildApkName(String8(outputAPKFile), split); err = writeAPK(bundle, outputPath, split); if (err != NO_ERROR) { - fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.string()); + fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.c_str()); goto bail; } } diff --git a/tools/aapt/CrunchCache.cpp b/tools/aapt/CrunchCache.cpp index 7b8a576b88d3..1f2febec2230 100644 --- a/tools/aapt/CrunchCache.cpp +++ b/tools/aapt/CrunchCache.cpp @@ -44,7 +44,7 @@ size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite) // This efficiently strips the source directory prefix from our path. // Also, String8 doesn't have a substring method so this is what we've // got to work with. - const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length(); + const char* rPathPtr = mSourceFiles.keyAt(0).c_str()+mSourcePath.length(); // Strip leading slash if present int offset = 0; if (rPathPtr[0] == OS_PATH_SEPARATOR) diff --git a/tools/aapt/DirectoryWalker.h b/tools/aapt/DirectoryWalker.h index 88031d04b2df..cea3a6eb0ecf 100644 --- a/tools/aapt/DirectoryWalker.h +++ b/tools/aapt/DirectoryWalker.h @@ -57,7 +57,7 @@ public: virtual bool openDir(String8 path) { mBasePath = path; dir = NULL; - dir = opendir(mBasePath.string() ); + dir = opendir(mBasePath.c_str() ); if (dir == NULL) return false; @@ -78,7 +78,7 @@ public: mEntry = *entryPtr; // Get stats String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name); - stat(fullPath.string(),&mStats); + stat(fullPath.c_str(),&mStats); return &mEntry; }; // Get the stats for the current entry diff --git a/tools/aapt/FileFinder.cpp b/tools/aapt/FileFinder.cpp index c9d0744a4463..a5c19806c804 100644 --- a/tools/aapt/FileFinder.cpp +++ b/tools/aapt/FileFinder.cpp @@ -59,14 +59,14 @@ bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions, String8 fullPath = basePath.appendPathCopy(entryName); // If this entry is a directory we'll recurse into it - if (isDirectory(fullPath.string()) ) { + if (isDirectory(fullPath.c_str()) ) { DirectoryWalker* copy = dw->clone(); findFiles(fullPath, extensions, fileStore,copy); delete copy; } // If this entry is a file, we'll pass it over to checkAndAddFile - if (isFile(fullPath.string()) ) { + if (isFile(fullPath.c_str()) ) { checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore); } } diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp index 627a231de5c8..c6c7e960ba2a 100644 --- a/tools/aapt/Images.cpp +++ b/tools/aapt/Images.cpp @@ -1328,13 +1328,13 @@ static bool read_png_protected(png_structp read_ptr, String8& printableName, png png_init_io(read_ptr, fp); - read_png(printableName.string(), read_ptr, read_info, imageInfo); + read_png(printableName.c_str(), read_ptr, read_info, imageInfo); const size_t nameLen = file->getPath().length(); if (nameLen > 6) { - const char* name = file->getPath().string(); + const char* name = file->getPath().c_str(); if (name[nameLen-5] == '9' && name[nameLen-6] == '.') { - if (do_9patch(printableName.string(), imageInfo) != NO_ERROR) { + if (do_9patch(printableName.c_str(), imageInfo) != NO_ERROR) { return false; } } @@ -1349,7 +1349,7 @@ static bool write_png_protected(png_structp write_ptr, String8& printableName, p return false; } - write_png(printableName.string(), write_ptr, write_info, *imageInfo, bundle); + write_png(printableName.c_str(), write_ptr, write_info, *imageInfo, bundle); return true; } @@ -1360,7 +1360,7 @@ status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& /* assets * String8 ext(file->getPath().getPathExtension()); // We currently only process PNG images. - if (strcmp(ext.string(), ".png") != 0) { + if (strcmp(ext.c_str(), ".png") != 0) { return NO_ERROR; } @@ -1371,7 +1371,7 @@ status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& /* assets * String8 printableName(file->getPrintableSource()); if (bundle->getVerbose()) { - printf("Processing image: %s\n", printableName.string()); + printf("Processing image: %s\n", printableName.c_str()); } png_structp read_ptr = NULL; @@ -1385,9 +1385,9 @@ status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& /* assets * status_t error = UNKNOWN_ERROR; - fp = fopen(file->getSourceFile().string(), "rb"); + fp = fopen(file->getSourceFile().c_str(), "rb"); if (fp == NULL) { - fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.string()); + fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.c_str()); goto bail; } @@ -1434,7 +1434,7 @@ status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& /* assets * size_t newSize = file->getSize(); float factor = ((float)newSize)/oldSize; int percent = (int)(factor*100); - printf(" (processed image %s: %d%% size of source)\n", printableName.string(), percent); + printf(" (processed image %s: %d%% size of source)\n", printableName.c_str(), percent); } bail: @@ -1450,7 +1450,7 @@ bail: if (error != NO_ERROR) { fprintf(stderr, "ERROR: Failure processing PNG image %s\n", - file->getPrintableSource().string()); + file->getPrintableSource().c_str()); } return error; } @@ -1470,13 +1470,13 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con status_t error = UNKNOWN_ERROR; if (bundle->getVerbose()) { - printf("Processing image to cache: %s => %s\n", source.string(), dest.string()); + printf("Processing image to cache: %s => %s\n", source.c_str(), dest.c_str()); } // Get a file handler to read from - fp = fopen(source.string(),"rb"); + fp = fopen(source.c_str(),"rb"); if (fp == NULL) { - fprintf(stderr, "%s ERROR: Unable to open PNG file\n", source.string()); + fprintf(stderr, "%s ERROR: Unable to open PNG file\n", source.c_str()); return error; } @@ -1507,7 +1507,7 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con png_init_io(read_ptr,fp); // Actually read data from the file - read_png(source.string(), read_ptr, read_info, &imageInfo); + read_png(source.c_str(), read_ptr, read_info, &imageInfo); // We're done reading so we can clean up // Find old file size before releasing handle @@ -1519,7 +1519,7 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con // Check to see if we're dealing with a 9-patch // If we are, process appropriately if (source.getBasePath().getPathExtension() == ".9") { - if (do_9patch(source.string(), &imageInfo) != NO_ERROR) { + if (do_9patch(source.c_str(), &imageInfo) != NO_ERROR) { return error; } } @@ -1541,9 +1541,9 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con } // Open up our destination file for writing - fp = fopen(dest.string(), "wb"); + fp = fopen(dest.c_str(), "wb"); if (!fp) { - fprintf(stderr, "%s ERROR: Unable to open PNG file\n", dest.string()); + fprintf(stderr, "%s ERROR: Unable to open PNG file\n", dest.c_str()); png_destroy_write_struct(&write_ptr, &write_info); return error; } @@ -1559,11 +1559,11 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con } // Actually write out to the new png - write_png(dest.string(), write_ptr, write_info, imageInfo, bundle); + write_png(dest.c_str(), write_ptr, write_info, imageInfo, bundle); if (bundle->getVerbose()) { // Find the size of our new file - FILE* reader = fopen(dest.string(), "rb"); + FILE* reader = fopen(dest.c_str(), "rb"); fseek(reader, 0, SEEK_END); size_t newSize = (size_t)ftell(reader); fclose(reader); @@ -1571,7 +1571,7 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con float factor = ((float)newSize)/oldSize; int percent = (int)(factor*100); printf(" (processed image to cache entry %s: %d%% size of source)\n", - dest.string(), percent); + dest.c_str(), percent); } //Clean up @@ -1588,7 +1588,7 @@ status_t postProcessImage(const Bundle* bundle, 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) { + if (strcmp(ext.c_str(), ".xml") == 0) { String16 resourceName(parseResourceName(file->getSourceFile().getPathLeaf())); return compileXmlFile(bundle, assets, resourceName, file, table); } diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp index f06643dcf784..a7ff5fabf495 100644 --- a/tools/aapt/Package.cpp +++ b/tools/aapt/Package.cpp @@ -8,6 +8,7 @@ #include "OutputSet.h" #include "ResourceTable.h" #include "ResourceFilter.h" +#include "Utils.h" #include <androidfw/misc.h> @@ -69,39 +70,39 @@ status_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet> * If "update" is set, update the contents of the existing archive. * Else, if "force" is set, remove the existing archive. */ - FileType fileType = getFileType(outputFile.string()); + FileType fileType = getFileType(outputFile.c_str()); if (fileType == kFileTypeNonexistent) { // okay, create it below } else if (fileType == kFileTypeRegular) { if (bundle->getUpdate()) { // okay, open it below } else if (bundle->getForce()) { - if (unlink(outputFile.string()) != 0) { - fprintf(stderr, "ERROR: unable to remove '%s': %s\n", outputFile.string(), + if (unlink(outputFile.c_str()) != 0) { + fprintf(stderr, "ERROR: unable to remove '%s': %s\n", outputFile.c_str(), strerror(errno)); goto bail; } } else { fprintf(stderr, "ERROR: '%s' exists (use '-f' to force overwrite)\n", - outputFile.string()); + outputFile.c_str()); goto bail; } } else { - fprintf(stderr, "ERROR: '%s' exists and is not a regular file\n", outputFile.string()); + fprintf(stderr, "ERROR: '%s' exists and is not a regular file\n", outputFile.c_str()); goto bail; } if (bundle->getVerbose()) { printf("%s '%s'\n", (fileType == kFileTypeNonexistent) ? "Creating" : "Opening", - outputFile.string()); + outputFile.c_str()); } status_t status; zip = new ZipFile; - status = zip->open(outputFile.string(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate); + status = zip->open(outputFile.c_str(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate); if (status != NO_ERROR) { fprintf(stderr, "ERROR: unable to open '%s' as Zip file for writing\n", - outputFile.string()); + outputFile.c_str()); goto bail; } @@ -112,7 +113,7 @@ status_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet> count = processAssets(bundle, zip, outputSet); if (count < 0) { fprintf(stderr, "ERROR: unable to process assets while packaging '%s'\n", - outputFile.string()); + outputFile.c_str()); result = count; goto bail; } @@ -124,7 +125,7 @@ status_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet> count = processJarFiles(bundle, zip); if (count < 0) { fprintf(stderr, "ERROR: unable to process jar files while packaging '%s'\n", - outputFile.string()); + outputFile.c_str()); result = count; goto bail; } @@ -169,12 +170,12 @@ status_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet> /* anything here? */ if (zip->getNumEntries() == 0) { if (bundle->getVerbose()) { - printf("Archive is empty -- removing %s\n", outputFile.getPathLeaf().string()); + printf("Archive is empty -- removing %s\n", outputFile.getPathLeaf().c_str()); } delete zip; // close the file so we can remove it in Win32 zip = NULL; - if (unlink(outputFile.string()) != 0) { - fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.string()); + if (unlink(outputFile.c_str()) != 0) { + fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.c_str()); } } @@ -187,9 +188,9 @@ status_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet> String8 dependencyFile = outputFile; dependencyFile.append(".d"); - FILE* fp = fopen(dependencyFile.string(), "a"); + FILE* fp = fopen(dependencyFile.c_str(), "a"); // Add this file to the dependency file - fprintf(fp, "%s \\\n", outputFile.string()); + fprintf(fp, "%s \\\n", outputFile.c_str()); fclose(fp); } @@ -199,10 +200,10 @@ bail: delete zip; // must close before remove in Win32 if (result != NO_ERROR) { if (bundle->getVerbose()) { - printf("Removing %s due to earlier failures\n", outputFile.string()); + printf("Removing %s due to earlier failures\n", outputFile.c_str()); } - if (unlink(outputFile.string()) != 0) { - fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.string()); + if (unlink(outputFile.c_str()) != 0) { + fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.c_str()); } } @@ -226,7 +227,7 @@ ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<const OutputSet>& o fprintf(stderr, "warning: null file being processed.\n"); } else { String8 storagePath(entry.getPath()); - storagePath.convertToResPath(); + convertToResPath(storagePath); if (!processFile(bundle, zip, storagePath, entry.getFile())) { return UNKNOWN_ERROR; } @@ -267,31 +268,31 @@ bool processFile(Bundle* bundle, ZipFile* zip, int fileNameLen = storageName.length(); int excludeExtensionLen = strlen(kExcludeExtension); if (fileNameLen > excludeExtensionLen - && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen), + && (0 == strcmp(storageName.c_str() + (fileNameLen - excludeExtensionLen), kExcludeExtension))) { - fprintf(stderr, "warning: '%s' not added to Zip\n", storageName.string()); + fprintf(stderr, "warning: '%s' not added to Zip\n", storageName.c_str()); return true; } - if (strcasecmp(storageName.getPathExtension().string(), ".gz") == 0) { + if (strcasecmp(storageName.getPathExtension().c_str(), ".gz") == 0) { fromGzip = true; storageName = storageName.getBasePath(); } if (bundle->getUpdate()) { - entry = zip->getEntryByName(storageName.string()); + entry = zip->getEntryByName(storageName.c_str()); if (entry != NULL) { /* file already exists in archive; there can be only one */ if (entry->getMarked()) { fprintf(stderr, "ERROR: '%s' exists twice (check for with & w/o '.gz'?)\n", - file->getPrintableSource().string()); + file->getPrintableSource().c_str()); return false; } if (!hasData) { const String8& srcName = file->getSourceFile(); time_t fileModWhen; - fileModWhen = getFileModDate(srcName.string()); + fileModWhen = getFileModDate(srcName.c_str()); if (fileModWhen == (time_t) -1) { // file existence tested earlier, return false; // not expecting an error here } @@ -299,14 +300,14 @@ bool processFile(Bundle* bundle, ZipFile* zip, if (fileModWhen > entry->getModWhen()) { // mark as deleted so add() will succeed if (bundle->getVerbose()) { - printf(" (removing old '%s')\n", storageName.string()); + printf(" (removing old '%s')\n", storageName.c_str()); } zip->remove(entry); } else { // version in archive is newer if (bundle->getVerbose()) { - printf(" (not updating '%s')\n", storageName.string()); + printf(" (not updating '%s')\n", storageName.c_str()); } entry->setMarked(true); return true; @@ -321,22 +322,22 @@ bool processFile(Bundle* bundle, ZipFile* zip, //android_setMinPriority(NULL, ANDROID_LOG_VERBOSE); if (fromGzip) { - result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry); + result = zip->addGzip(file->getSourceFile().c_str(), storageName.c_str(), &entry); } else if (!hasData) { /* don't compress certain files, e.g. PNGs */ int compressionMethod = bundle->getCompressionMethod(); if (!okayToCompress(bundle, storageName)) { compressionMethod = ZipEntry::kCompressStored; } - result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod, + result = zip->add(file->getSourceFile().c_str(), storageName.c_str(), compressionMethod, &entry); } else { - result = zip->add(file->getData(), file->getSize(), storageName.string(), + result = zip->add(file->getData(), file->getSize(), storageName.c_str(), file->getCompressionMethod(), &entry); } if (result == NO_ERROR) { if (bundle->getVerbose()) { - printf(" '%s'%s", storageName.string(), fromGzip ? " (from .gz)" : ""); + printf(" '%s'%s", storageName.c_str(), fromGzip ? " (from .gz)" : ""); if (entry->getCompressionMethod() == ZipEntry::kCompressStored) { printf(" (not compressed)\n"); } else { @@ -348,10 +349,10 @@ bool processFile(Bundle* bundle, ZipFile* zip, } else { if (result == ALREADY_EXISTS) { fprintf(stderr, " Unable to add '%s': file already in archive (try '-u'?)\n", - file->getPrintableSource().string()); + file->getPrintableSource().c_str()); } else { fprintf(stderr, " Unable to add '%s': Zip add failed (%d)\n", - file->getPrintableSource().string(), result); + file->getPrintableSource().c_str(), result); } return false; } @@ -372,7 +373,7 @@ bool okayToCompress(Bundle* bundle, const String8& pathName) return true; for (i = 0; i < NELEM(kNoCompressExt); i++) { - if (strcasecmp(ext.string(), kNoCompressExt[i]) == 0) + if (strcasecmp(ext.c_str(), kNoCompressExt[i]) == 0) return false; } @@ -383,7 +384,7 @@ bool okayToCompress(Bundle* bundle, const String8& pathName) if (pos < 0) { continue; } - const char* path = pathName.string(); + const char* path = pathName.c_str(); if (strcasecmp(path + pos, str) == 0) { return false; } diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index dd3ebdbdea09..9c944e0de075 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -15,6 +15,7 @@ #include "ResourceTable.h" #include "StringPool.h" #include "Symbol.h" +#include "Utils.h" #include "WorkQueue.h" #include "XMLNode.h" @@ -57,8 +58,8 @@ public: String8 parseResourceName(const String8& leaf) { - const char* firstDot = strchr(leaf.string(), '.'); - const char* str = leaf.string(); + const char* firstDot = strchr(leaf.c_str(), '.'); + const char* str = leaf.c_str(); if (firstDot) { return String8(str, firstDot-str); @@ -132,7 +133,7 @@ public: mParams = file->getGroupEntry().toParams(); if (kIsDebug) { printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n", - group->getPath().string(), mParams.mcc, mParams.mnc, + group->getPath().c_str(), mParams.mcc, mParams.mnc, mParams.language[0] ? mParams.language[0] : '-', mParams.language[1] ? mParams.language[1] : '-', mParams.country[0] ? mParams.country[0] : '-', @@ -147,12 +148,12 @@ public: mBaseName = parseResourceName(leaf); if (mBaseName == "") { fprintf(stderr, "Error: malformed resource filename %s\n", - file->getPrintableSource().string()); + file->getPrintableSource().c_str()); return UNKNOWN_ERROR; } if (kIsDebug) { - printf("file name=%s\n", mBaseName.string()); + printf("file name=%s\n", mBaseName.c_str()); } return NO_ERROR; @@ -222,7 +223,7 @@ static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets, { if (grp->getFiles().size() != 1) { fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", - grp->getFiles().valueAt(0)->getPrintableSource().string()); + grp->getFiles().valueAt(0)->getPrintableSource().c_str()); } sp<AaptFile> file = grp->getFiles().valueAt(0); @@ -243,20 +244,20 @@ static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets, size_t len; if (code != ResXMLTree::START_TAG) { fprintf(stderr, "%s:%d: No start tag found\n", - file->getPrintableSource().string(), block.getLineNumber()); + file->getPrintableSource().c_str(), block.getLineNumber()); return UNKNOWN_ERROR; } - if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) { + if (strcmp16(block.getElementName(&len), String16("manifest").c_str()) != 0) { fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n", - file->getPrintableSource().string(), block.getLineNumber(), - String8(block.getElementName(&len)).string()); + file->getPrintableSource().c_str(), block.getLineNumber(), + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } ssize_t nameIndex = block.indexOfAttribute(NULL, "package"); if (nameIndex < 0) { fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n", - file->getPrintableSource().string(), block.getLineNumber()); + file->getPrintableSource().c_str(), block.getLineNumber()); return UNKNOWN_ERROR; } @@ -264,19 +265,19 @@ static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets, ssize_t revisionCodeIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "revisionCode"); if (revisionCodeIndex >= 0) { - bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).string()); + bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).c_str()); } String16 uses_sdk16("uses-sdk"); while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::START_TAG) { - if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) { + if (strcmp16(block.getElementName(&len), uses_sdk16.c_str()) == 0) { ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "minSdkVersion"); if (minSdkIndex >= 0) { const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len); - const char* minSdk8 = strdup(String8(minSdk16).string()); + const char* minSdk8 = strdup(String8(minSdk16).c_str()); bundle->setManifestMinSdkVersion(minSdk8); } } @@ -305,23 +306,23 @@ static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets, while ((res=it.next()) == NO_ERROR) { if (bundle->getVerbose()) { printf(" (new resource id %s from %s)\n", - it.getBaseName().string(), it.getFile()->getPrintableSource().string()); + it.getBaseName().c_str(), it.getFile()->getPrintableSource().c_str()); } String16 baseName(it.getBaseName()); - const char16_t* str = baseName.string(); + const char16_t* str = baseName.c_str(); const char16_t* const end = str + baseName.size(); while (str < end) { if (!((*str >= 'a' && *str <= 'z') || (*str >= '0' && *str <= '9') || *str == '_' || *str == '.')) { fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n", - it.getPath().string()); + it.getPath().c_str()); hasErrors = true; } str++; } String8 resPath = it.getPath(); - resPath.convertToResPath(); + convertToResPath(resPath); status_t result = table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()), type16, @@ -413,7 +414,7 @@ static void collect_files(const sp<AaptDir>& dir, sp<ResourceTypeSet> set = new ResourceTypeSet(); if (kIsDebug) { printf("Creating new resource type set for leaf %s with group %s (%p)\n", - leafName.string(), group->getPath().string(), group.get()); + leafName.c_str(), group->getPath().c_str(), group.get()); } set->add(leafName, group); resources->add(resType, set); @@ -423,21 +424,21 @@ static void collect_files(const sp<AaptDir>& dir, if (index < 0) { if (kIsDebug) { printf("Adding to resource type set for leaf %s group %s (%p)\n", - leafName.string(), group->getPath().string(), group.get()); + leafName.c_str(), group->getPath().c_str(), group.get()); } set->add(leafName, group); } else { sp<AaptGroup> existingGroup = set->valueAt(index); if (kIsDebug) { printf("Extending to resource type set for leaf %s group %s (%p)\n", - leafName.string(), group->getPath().string(), group.get()); + leafName.c_str(), group->getPath().c_str(), group.get()); } for (size_t j=0; j<files.size(); j++) { if (kIsDebug) { printf("Adding file %s in group %s resType %s\n", - files.valueAt(j)->getSourceFile().string(), - files.keyAt(j).toDirName(String8()).string(), - resType.string()); + files.valueAt(j)->getSourceFile().c_str(), + files.keyAt(j).toDirName(String8()).c_str(), + resType.c_str()); } existingGroup->addFile(files.valueAt(j)); } @@ -455,14 +456,14 @@ static void collect_files(const sp<AaptAssets>& ass, for (int i=0; i<N; i++) { const sp<AaptDir>& d = dirs.itemAt(i); if (kIsDebug) { - printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(), - d->getLeaf().string()); + printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().c_str(), + d->getLeaf().c_str()); } collect_files(d, resources); // don't try to include the res dir if (kIsDebug) { - printf("Removing dir leaf %s\n", d->getLeaf().string()); + printf("Removing dir leaf %s\n", d->getLeaf().c_str()); } ass->removeDir(d->getLeaf()); } @@ -490,8 +491,8 @@ static int validateAttr(const String8& path, const ResTable& table, int strIdx; if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) { fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr, + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr, value.data); return ATTR_NOT_FOUND; } @@ -502,12 +503,12 @@ static int validateAttr(const String8& path, const ResTable& table, str = pool->stringAt(value.data, &len); } printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr, - specFlags, strIdx, str != NULL ? String8(str).string() : "???"); + specFlags, strIdx, str != NULL ? String8(str).c_str() : "???"); #endif if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) { fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr, + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr, specFlags); return ATTR_NOT_FOUND; } @@ -515,20 +516,20 @@ static int validateAttr(const String8& path, const ResTable& table, if (value.dataType == Res_value::TYPE_STRING) { if (pool == NULL) { fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr); return ATTR_NOT_FOUND; } if ((str = UnpackOptionalString(pool->stringAt(value.data), &len)) == NULL) { fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr); return ATTR_NOT_FOUND; } } else { fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr, + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr, value.dataType); return ATTR_NOT_FOUND; } @@ -546,30 +547,30 @@ static int validateAttr(const String8& path, const ResTable& table, } if (!okay) { fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr, (char)str[i]); + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr, (char)str[i]); return (int)i; } } } if (*str == ' ') { fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr); return ATTR_LEADING_SPACES; } if (len != 0 && str[len-1] == ' ') { fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr); return ATTR_TRAILING_SPACES; } return ATTR_OKAY; } if (required) { fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); + path.c_str(), parser.getLineNumber(), + String8(parser.getElementName(&len)).c_str(), attr); return ATTR_NOT_FOUND; } return ATTR_OKAY; @@ -584,7 +585,7 @@ static void checkForIds(const String8& path, ResXMLParser& parser) ssize_t index = parser.indexOfAttribute(NULL, "id"); if (index >= 0) { fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n", - path.string(), parser.getLineNumber()); + path.c_str(), parser.getLineNumber()); } } } @@ -618,7 +619,7 @@ static bool applyFileOverlay(Bundle *bundle, size_t overlayCount = overlaySet->size(); for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) { if (bundle->getVerbose()) { - printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string()); + printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).c_str()); } ssize_t baseIndex = -1; if (baseSet->get() != NULL) { @@ -638,11 +639,11 @@ static bool applyFileOverlay(Bundle *bundle, baseGroup->getFiles(); for (size_t i=0; i < baseFiles.size(); i++) { printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i, - baseFiles.keyAt(i).toString().string()); + baseFiles.keyAt(i).toString().c_str()); } for (size_t i=0; i < overlayFiles.size(); i++) { printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i, - overlayFiles.keyAt(i).toString().string()); + overlayFiles.keyAt(i).toString().c_str()); } } @@ -657,16 +658,16 @@ static bool applyFileOverlay(Bundle *bundle, if (bundle->getVerbose()) { printf("found a match (" ZD ") for overlay file %s, for flavor %s\n", (ZD_TYPE) baseFileIndex, - overlayGroup->getLeaf().string(), - overlayFiles.keyAt(overlayGroupIndex).toString().string()); + overlayGroup->getLeaf().c_str(), + overlayFiles.keyAt(overlayGroupIndex).toString().c_str()); } baseGroup->removeFile(baseFileIndex); } else { // didn't find a match fall through and add it.. if (true || bundle->getVerbose()) { printf("nothing matches overlay file %s, for flavor %s\n", - overlayGroup->getLeaf().string(), - overlayFiles.keyAt(overlayGroupIndex).toString().string()); + overlayGroup->getLeaf().c_str(), + overlayFiles.keyAt(overlayGroupIndex).toString().c_str()); } } baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex)); @@ -728,7 +729,7 @@ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, if (errorOnFailedInsert) { fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);" " cannot insert new value %s.\n", - String8(attr).string(), String8(ns).string(), value); + String8(attr).c_str(), String8(ns).c_str(), value); return false; } @@ -763,7 +764,7 @@ static void fullyQualifyClassName(const String8& package, const sp<XMLNode>& nod // .asdf .a.b --> package.asdf package.a.b // asdf.adsf --> asdf.asdf String8 className; - const char* p = name.string(); + const char* p = name.c_str(); const char* q = strchr(p, '.'); if (p == q) { className += package; @@ -776,7 +777,7 @@ static void fullyQualifyClassName(const String8& package, const sp<XMLNode>& nod className += name; } if (kIsDebug) { - printf("Qualifying class '%s' to '%s'", name.string(), className.string()); + printf("Qualifying class '%s' to '%s'", name.c_str(), className.c_str()); } attr->string.setTo(String16(className)); } @@ -810,7 +811,7 @@ static void massageRoundIconSupport(const String16& iconRef, const String16& rou const char* err; String16 iconPackage, iconType, iconName; - if (!ResTable::expandResourceRef(iconRef.string(), iconRef.size(), &iconPackage, &iconType, + if (!ResTable::expandResourceRef(iconRef.c_str(), iconRef.size(), &iconPackage, &iconType, &iconName, NULL, &table->getAssetsPackage(), &err, &publicOnly)) { // Errors will be raised in later XML compilation. @@ -824,7 +825,7 @@ static void massageRoundIconSupport(const String16& iconRef, const String16& rou } String16 roundIconPackage, roundIconType, roundIconName; - if (!ResTable::expandResourceRef(roundIconRef.string(), roundIconRef.size(), &roundIconPackage, + if (!ResTable::expandResourceRef(roundIconRef.c_str(), roundIconRef.size(), &roundIconPackage, &roundIconType, &roundIconName, NULL, &table->getAssetsPackage(), &err, &publicOnly)) { // Errors will be raised in later XML compilation. @@ -839,9 +840,9 @@ static void massageRoundIconSupport(const String16& iconRef, const String16& rou return; } - String16 aliasValue = String16(String8::format("@%s:%s/%s", String8(iconPackage).string(), - String8(iconType).string(), - String8(iconName).string())); + String16 aliasValue = String16(String8::format("@%s:%s/%s", String8(iconPackage).c_str(), + String8(iconType).c_str(), + String8(iconName).c_str())); // Add an equivalent v26 entry to the roundIcon for each v26 variant of the regular icon. const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& configList = @@ -872,7 +873,7 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root) const XMLNode::attribute_entry* attr = root->getAttribute( String16(RESOURCES_ANDROID_NAMESPACE), String16("versionCode")); if (attr != NULL) { - bundle->setVersionCode(strdup(String8(attr->string).string())); + bundle->setVersionCode(strdup(String8(attr->string).c_str())); } } @@ -883,7 +884,7 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root) const XMLNode::attribute_entry* attr = root->getAttribute( String16(RESOURCES_ANDROID_NAMESPACE), String16("versionName")); if (attr != NULL) { - bundle->setVersionName(strdup(String8(attr->string).string())); + bundle->setVersionName(strdup(String8(attr->string).c_str())); } } @@ -914,7 +915,7 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root) const XMLNode::attribute_entry* attr = vers->getAttribute( String16(RESOURCES_ANDROID_NAMESPACE), String16("minSdkVersion")); if (attr != NULL) { - bundle->setMinSdkVersion(strdup(String8(attr->string).string())); + bundle->setMinSdkVersion(strdup(String8(attr->string).c_str())); } } @@ -970,7 +971,7 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root) String8 origPackage(attr->string); attr->string.setTo(String16(manifestPackageNameOverride)); if (kIsDebug) { - printf("Overriding package '%s' to be '%s'\n", origPackage.string(), + printf("Overriding package '%s' to be '%s'\n", origPackage.c_str(), manifestPackageNameOverride); } @@ -1071,7 +1072,7 @@ enum { static ssize_t extractPlatformBuildVersion(const ResTable& table, ResXMLTree& tree, Bundle* bundle) { // First check if we should be recording the compileSdkVersion* attributes. static const String16 compileSdkVersionName("android:attr/compileSdkVersion"); - const bool useCompileSdkVersion = table.identifierForName(compileSdkVersionName.string(), + const bool useCompileSdkVersion = table.identifierForName(compileSdkVersionName.c_str(), compileSdkVersionName.size()) != 0u; size_t len; @@ -1223,7 +1224,7 @@ status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& a // Add the 'revisionCode' attribute, which is set to the original revisionCode. if (bundle->getRevisionCode().size() > 0) { if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "revisionCode", - bundle->getRevisionCode().string(), true, true)) { + bundle->getRevisionCode().c_str(), true, true)) { return UNKNOWN_ERROR; } } @@ -1270,7 +1271,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil } if (kIsDebug) { - printf("Creating resources for package %s\n", assets->getPackage().string()); + printf("Creating resources for package %s\n", assets->getPackage().c_str()); } // Set the private symbols package if it was declared. @@ -1804,7 +1805,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil flattenedTable, split->isBase()); if (err != NO_ERROR) { fprintf(stderr, "Failed to generate resource table for split '%s'\n", - split->getPrintableName().string()); + split->getPrintableName().c_str()); return err; } split->addEntry(String8("resources.arsc"), flattenedTable); @@ -1821,7 +1822,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil err = resTable.add(flattenedTable->getData(), flattenedTable->getSize()); if (err != NO_ERROR) { fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n", - split->getPrintableName().string()); + split->getPrintableName().c_str()); return err; } @@ -1849,7 +1850,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil if (block < 0) { hasError = true; SourcePos().error("%s has no definition for density split '%s'", - symbol.toString().string(), config.toString().string()); + symbol.toString().c_str(), config.toString().c_str()); if (bundle->getVerbose()) { const Vector<SymbolDefinition>& defs = densityVaryingResources[k]; @@ -1857,7 +1858,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil for (size_t d = 0; d < defCount; d++) { const SymbolDefinition& def = defs[d]; def.source.error("%s has definition for %s", - symbol.toString().string(), def.config.toString().string()); + symbol.toString().c_str(), def.config.toString().c_str()); } if (defCount < defs.size()) { @@ -1880,7 +1881,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil generatedManifest, &table); if (err != NO_ERROR) { fprintf(stderr, "Failed to generate AndroidManifest.xml for split '%s'\n", - split->getPrintableName().string()); + split->getPrintableName().c_str()); return err; } split->addEntry(String8("AndroidManifest.xml"), generatedManifest); @@ -1960,7 +1961,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil if (block.getElementNamespace(&len) != NULL) { continue; } - if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) { + if (strcmp16(block.getElementName(&len), manifest16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, NULL, "package", packageIdentChars, true) != ATTR_OKAY) { hasErrors = true; @@ -1969,10 +1970,10 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil "sharedUserId", packageIdentChars, false) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0 - || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), permission16.c_str()) == 0 + || strcmp16(block.getElementName(&len), permission_group16.c_str()) == 0) { const bool isGroup = strcmp16(block.getElementName(&len), - permission_group16.string()) == 0; + permission_group16.c_str()) == 0; if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", isGroup ? packageIdentCharsWithTheStupid : packageIdentChars, true) != ATTR_OKAY) { @@ -2002,8 +2003,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil const char16_t* id = block.getAttributeStringValue(index, &len); if (id == NULL) { fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", - manifestPath.string(), block.getLineNumber(), - String8(block.getElementName(&len)).string()); + manifestPath.c_str(), block.getLineNumber(), + String8(block.getElementName(&len)).c_str()); hasErrors = true; break; } @@ -2038,23 +2039,23 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil if (begins_with_digit || (e != p && *(e-1) != '.')) { fprintf(stderr, "%s:%d: Permission name <%s> is not a valid Java symbol\n", - manifestPath.string(), block.getLineNumber(), idStr.string()); + manifestPath.c_str(), block.getLineNumber(), idStr.c_str()); hasErrors = true; } syms->addStringSymbol(String8(e), idStr, srcPos); const char16_t* cmt = block.getComment(&len); if (cmt != NULL && *cmt != 0) { - //printf("Comment of %s: %s\n", String8(e).string(), - // String8(cmt).string()); + //printf("Comment of %s: %s\n", String8(e).c_str(), + // String8(cmt).c_str()); syms->appendComment(String8(e), String16(cmt), srcPos); } syms->makeSymbolPublic(String8(e), srcPos); - } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), uses_permission16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", packageIdentChars, true) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), instrumentation16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", classIdentChars, true) != ATTR_OKAY) { hasErrors = true; @@ -2064,7 +2065,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil packageIdentChars, true) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), application16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", classIdentChars, false) != ATTR_OKAY) { hasErrors = true; @@ -2084,7 +2085,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil processIdentChars, false) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), provider16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", classIdentChars, true) != ATTR_OKAY) { hasErrors = true; @@ -2104,9 +2105,9 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil processIdentChars, false) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), service16.string()) == 0 - || strcmp16(block.getElementName(&len), receiver16.string()) == 0 - || strcmp16(block.getElementName(&len), activity16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), service16.c_str()) == 0 + || strcmp16(block.getElementName(&len), receiver16.c_str()) == 0 + || strcmp16(block.getElementName(&len), activity16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", classIdentChars, true) != ATTR_OKAY) { hasErrors = true; @@ -2126,14 +2127,14 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil processIdentChars, false) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), action16.string()) == 0 - || strcmp16(block.getElementName(&len), category16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), action16.c_str()) == 0 + || strcmp16(block.getElementName(&len), category16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "name", packageIdentChars, true) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), data16.c_str()) == 0) { if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, "mimeType", typeIdentChars, true) != ATTR_OKAY) { @@ -2144,13 +2145,13 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil schemeIdentChars, true) != ATTR_OKAY) { hasErrors = true; } - } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), feature_group16.c_str()) == 0) { int depth = 1; while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code > ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::START_TAG) { depth++; - if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) { + if (strcmp16(block.getElementName(&len), uses_feature16.c_str()) == 0) { ssize_t idx = block.indexOfAttribute( RESOURCES_ANDROID_NAMESPACE, "required"); if (idx < 0) { @@ -2162,7 +2163,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil fprintf(stderr, "%s:%d: Tag <uses-feature> can not have " "android:required=\"false\" when inside a " "<feature-group> tag.\n", - manifestPath.string(), block.getLineNumber()); + manifestPath.c_str(), block.getLineNumber()); hasErrors = true; } } @@ -2222,7 +2223,7 @@ static String8 flattenSymbol(const String8& symbol) { static String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) { ssize_t colon = symbol.find(":", 0); if (colon >= 0) { - return String8(symbol.string(), colon); + return String8(symbol.c_str(), colon); } return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage(); } @@ -2230,7 +2231,7 @@ static String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& ass static String8 getSymbolName(const String8& symbol) { ssize_t colon = symbol.find(":", 0); if (colon >= 0) { - return String8(symbol.string() + colon + 1); + return String8(symbol.c_str() + colon + 1); } return symbol; } @@ -2245,7 +2246,7 @@ static String16 getAttributeComment(const sp<AaptAssets>& assets, asym = asym->getNestedSymbols().valueFor(String8("attr")); if (asym != NULL) { //printf("Got attrs symbols! comment %s=%s\n", - // name.string(), String8(asym->getComment(name)).string()); + // name.c_str(), String8(asym->getComment(name)).c_str()); if (outTypeComment != NULL) { *outTypeComment = asym->getTypeComment(name); } @@ -2276,8 +2277,8 @@ static status_t writeResourceLoadedCallbackForLayoutClasses( "%sfor(int i = 0; i < styleable.%s.length; ++i) {\n" "%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n" "%s}\n", - indentStr, nclassName.string(), - getIndentSpace(indent+1), nclassName.string(), nclassName.string(), + indentStr, nclassName.c_str(), + getIndentSpace(indent+1), nclassName.c_str(), nclassName.c_str(), indentStr); } @@ -2303,8 +2304,8 @@ static status_t writeResourceLoadedCallback( String8 flat_name(flattenSymbol(sym.name)); fprintf(fp, "%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n", - getIndentSpace(indent), className.string(), flat_name.string(), - className.string(), flat_name.string()); + getIndentSpace(indent), className.c_str(), flat_name.c_str(), + className.c_str(), flat_name.c_str()); } N = symbols->getNestedSymbols().size(); @@ -2365,12 +2366,12 @@ static status_t writeLayoutClasses( String16 name16(sym.name); uint32_t typeSpecFlags; code = assets->getIncludedResources().identifierForName( - name16.string(), name16.size(), - attr16.string(), attr16.size(), - package16.string(), package16.size(), &typeSpecFlags); + name16.c_str(), name16.size(), + attr16.c_str(), attr16.size(), + package16.c_str(), package16.size(), &typeSpecFlags); if (code == 0) { fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", - nclassName.string(), sym.name.string()); + nclassName.c_str(), sym.name.c_str()); hasErrors = true; } isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; @@ -2388,9 +2389,9 @@ static status_t writeLayoutClasses( if (comment.size() > 0) { String8 cmt(comment); ann.preprocessComment(cmt); - fprintf(fp, "%s\n", cmt.string()); + fprintf(fp, "%s\n", cmt.c_str()); } else { - fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string()); + fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.c_str()); } bool hasTable = false; for (a=0; a<NA; a++) { @@ -2423,7 +2424,7 @@ static status_t writeLayoutClasses( continue; } if (comment.size() > 0) { - const char16_t* p = comment.string(); + const char16_t* p = comment.c_str(); while (*p != 0 && *p != '.') { if (*p == '{') { while (*p != 0 && *p != '}') { @@ -2436,14 +2437,14 @@ static status_t writeLayoutClasses( if (*p == '.') { p++; } - comment = String16(comment.string(), p-comment.string()); + comment = String16(comment.c_str(), p-comment.c_str()); } fprintf(fp, "%s <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n", - indentStr, nclassName.string(), - flattenSymbol(name8).string(), - getSymbolPackage(name8, assets, true).string(), - getSymbolName(name8).string(), - String8(comment).string()); + indentStr, nclassName.c_str(), + flattenSymbol(name8).c_str(), + getSymbolPackage(name8, assets, true).c_str(), + getSymbolName(name8).c_str(), + String8(comment).c_str()); } } if (hasTable) { @@ -2457,8 +2458,8 @@ static status_t writeLayoutClasses( continue; } fprintf(fp, "%s @see #%s_%s\n", - indentStr, nclassName.string(), - flattenSymbol(sym.name).string()); + indentStr, nclassName.c_str(), + flattenSymbol(sym.name).c_str()); } } fprintf(fp, "%s */\n", getIndentSpace(indent)); @@ -2468,7 +2469,7 @@ static status_t writeLayoutClasses( fprintf(fp, "%spublic static final int[] %s = {\n" "%s", - indentStr, nclassName.string(), + indentStr, nclassName.c_str(), getIndentSpace(indent+1)); for (a=0; a<NA; a++) { @@ -2503,11 +2504,11 @@ static status_t writeLayoutClasses( uint32_t typeSpecFlags = 0; String16 name16(sym.name); assets->getIncludedResources().identifierForName( - name16.string(), name16.size(), - attr16.string(), attr16.size(), - package16.string(), package16.size(), &typeSpecFlags); - //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), - // String8(attr16).string(), String8(name16).string(), typeSpecFlags); + name16.c_str(), name16.size(), + attr16.c_str(), attr16.size(), + package16.c_str(), package16.size(), &typeSpecFlags); + //printf("%s:%s/%s: 0x%08x\n", String8(package16).c_str(), + // String8(attr16).c_str(), String8(name16).c_str(), typeSpecFlags); const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; AnnotationProcessor ann; @@ -2516,20 +2517,20 @@ static status_t writeLayoutClasses( String8 cmt(comment); ann.preprocessComment(cmt); fprintf(fp, "%s <p>\n%s @attr description\n", indentStr, indentStr); - fprintf(fp, "%s %s\n", indentStr, cmt.string()); + fprintf(fp, "%s %s\n", indentStr, cmt.c_str()); } else { fprintf(fp, "%s <p>This symbol is the offset where the {@link %s.R.attr#%s}\n" "%s attribute's value can be found in the {@link #%s} array.\n", indentStr, - getSymbolPackage(name8, assets, pub).string(), - getSymbolName(name8).string(), - indentStr, nclassName.string()); + getSymbolPackage(name8, assets, pub).c_str(), + getSymbolName(name8).c_str(), + indentStr, nclassName.c_str()); } if (typeComment.size() > 0) { String8 cmt(typeComment); ann.preprocessComment(cmt); - fprintf(fp, "\n\n%s %s\n", indentStr, cmt.string()); + fprintf(fp, "\n\n%s %s\n", indentStr, cmt.c_str()); } if (comment.size() > 0) { if (pub) { @@ -2537,16 +2538,16 @@ static status_t writeLayoutClasses( "%s <p>This corresponds to the global attribute\n" "%s resource symbol {@link %s.R.attr#%s}.\n", indentStr, indentStr, - getSymbolPackage(name8, assets, true).string(), - getSymbolName(name8).string()); + getSymbolPackage(name8, assets, true).c_str(), + getSymbolName(name8).c_str()); } else { fprintf(fp, "%s <p>This is a private symbol.\n", indentStr); } } fprintf(fp, "%s @attr name %s:%s\n", indentStr, - getSymbolPackage(name8, assets, pub).string(), - getSymbolName(name8).string()); + getSymbolPackage(name8, assets, pub).c_str(), + getSymbolName(name8).c_str()); fprintf(fp, "%s*/\n", indentStr); ann.printAnnotations(fp, indentStr); @@ -2556,8 +2557,8 @@ static status_t writeLayoutClasses( fprintf(fp, id_format, - indentStr, nclassName.string(), - flattenSymbol(name8).string(), (int)pos); + indentStr, nclassName.c_str(), + flattenSymbol(name8).c_str(), (int)pos); } } } @@ -2598,12 +2599,12 @@ static status_t writeTextLayoutClasses( String16 name16(sym.name); uint32_t typeSpecFlags; code = assets->getIncludedResources().identifierForName( - name16.string(), name16.size(), - attr16.string(), attr16.size(), - package16.string(), package16.size(), &typeSpecFlags); + name16.c_str(), name16.size(), + attr16.c_str(), attr16.size(), + package16.c_str(), package16.size(), &typeSpecFlags); if (code == 0) { fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", - nclassName.string(), sym.name.string()); + nclassName.c_str(), sym.name.c_str()); hasErrors = true; } isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; @@ -2615,7 +2616,7 @@ static status_t writeTextLayoutClasses( NA = idents.size(); - fprintf(fp, "int[] styleable %s {", nclassName.string()); + fprintf(fp, "int[] styleable %s {", nclassName.c_str()); for (a=0; a<NA; a++) { if (a != 0) { @@ -2645,17 +2646,17 @@ static status_t writeTextLayoutClasses( uint32_t typeSpecFlags = 0; String16 name16(sym.name); assets->getIncludedResources().identifierForName( - name16.string(), name16.size(), - attr16.string(), attr16.size(), - package16.string(), package16.size(), &typeSpecFlags); - //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), - // String8(attr16).string(), String8(name16).string(), typeSpecFlags); + name16.c_str(), name16.size(), + attr16.c_str(), attr16.size(), + package16.c_str(), package16.size(), &typeSpecFlags); + //printf("%s:%s/%s: 0x%08x\n", String8(package16).c_str(), + // String8(attr16).c_str(), String8(name16).c_str(), typeSpecFlags); //const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; fprintf(fp, "int styleable %s_%s %d\n", - nclassName.string(), - flattenSymbol(name8).string(), (int)pos); + nclassName.c_str(), + flattenSymbol(name8).c_str(), (int)pos); } } } @@ -2670,7 +2671,7 @@ static status_t writeSymbolClass( { fprintf(fp, "%spublic %sfinal class %s {\n", getIndentSpace(indent), - indent != 0 ? "static " : "", className.string()); + indent != 0 ? "static " : "", className.c_str()); indent++; size_t i; @@ -2699,7 +2700,7 @@ static status_t writeSymbolClass( ann.preprocessComment(cmt); fprintf(fp, "%s/** %s\n", - getIndentSpace(indent), cmt.string()); + getIndentSpace(indent), cmt.c_str()); } String16 typeComment(sym.typeComment); if (typeComment.size() > 0) { @@ -2708,10 +2709,10 @@ static status_t writeSymbolClass( if (!haveComment) { haveComment = true; fprintf(fp, - "%s/** %s\n", getIndentSpace(indent), cmt.string()); + "%s/** %s\n", getIndentSpace(indent), cmt.c_str()); } else { fprintf(fp, - "%s %s\n", getIndentSpace(indent), cmt.string()); + "%s %s\n", getIndentSpace(indent), cmt.c_str()); } } if (haveComment) { @@ -2720,7 +2721,7 @@ static status_t writeSymbolClass( ann.printAnnotations(fp, getIndentSpace(indent)); fprintf(fp, id_format, getIndentSpace(indent), - flattenSymbol(name8).string(), (int)sym.int32Val); + flattenSymbol(name8).c_str(), (int)sym.int32Val); } for (i=0; i<N; i++) { @@ -2740,13 +2741,13 @@ static status_t writeSymbolClass( fprintf(fp, "%s/** %s\n" "%s */\n", - getIndentSpace(indent), cmt.string(), + getIndentSpace(indent), cmt.c_str(), getIndentSpace(indent)); } ann.printAnnotations(fp, getIndentSpace(indent)); fprintf(fp, "%spublic static final String %s=\"%s\";\n", getIndentSpace(indent), - flattenSymbol(name8).string(), sym.stringVal.string()); + flattenSymbol(name8).c_str(), sym.stringVal.c_str()); } sp<AaptSymbols> styleableSymbols; @@ -2805,8 +2806,8 @@ static status_t writeTextSymbolClass( String8 name8(sym.name); fprintf(fp, "int %s %s 0x%08x\n", - className.string(), - flattenSymbol(name8).string(), (int)sym.int32Val); + className.c_str(), + flattenSymbol(name8).c_str(), (int)sym.int32Val); } N = symbols->getNestedSymbols().size(); @@ -2844,7 +2845,7 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, if (bundle->getMakePackageDirs()) { const String8& pkg(package); - const char* last = pkg.string(); + const char* last = pkg.c_str(); const char* s = last-1; do { s++; @@ -2852,9 +2853,9 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, String8 part(last, s-last); dest.appendPath(part); #ifdef _WIN32 - _mkdir(dest.string()); + _mkdir(dest.c_str()); #else - mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); + mkdir(dest.c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); #endif last = s+1; } @@ -2862,14 +2863,14 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, } dest.appendPath(className); dest.append(".java"); - FILE* fp = fopen(dest.string(), "w+"); + FILE* fp = fopen(dest.c_str(), "w+"); if (fp == NULL) { fprintf(stderr, "ERROR: Unable to open class file %s: %s\n", - dest.string(), strerror(errno)); + dest.c_str(), strerror(errno)); return UNKNOWN_ERROR; } if (bundle->getVerbose()) { - printf(" Writing symbols for class %s.\n", className.string()); + printf(" Writing symbols for class %s.\n", className.c_str()); } fprintf(fp, @@ -2880,7 +2881,7 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, " * should not be modified by hand.\n" " */\n" "\n" - "package %s;\n\n", package.string()); + "package %s;\n\n", package.c_str()); status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0, bundle->getNonConstantId(), emitCallback); @@ -2894,14 +2895,14 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, textDest.appendPath(className); textDest.append(".txt"); - FILE* fp = fopen(textDest.string(), "w+"); + FILE* fp = fopen(textDest.c_str(), "w+"); if (fp == NULL) { fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n", - textDest.string(), strerror(errno)); + textDest.c_str(), strerror(errno)); return UNKNOWN_ERROR; } if (bundle->getVerbose()) { - printf(" Writing text symbols for class %s.\n", className.string()); + printf(" Writing text symbols for class %s.\n", className.c_str()); } status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols, @@ -2919,8 +2920,8 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, String8 dependencyFile(bundle->getRClassDir()); dependencyFile.appendPath("R.java.d"); - FILE *fp = fopen(dependencyFile.string(), "a"); - fprintf(fp,"%s \\\n", dest.string()); + FILE *fp = fopen(dependencyFile.c_str(), "a"); + fprintf(fp,"%s \\\n", dest.c_str()); fclose(fp); } } @@ -2956,7 +2957,7 @@ addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName, // asdf --> package.asdf // .asdf .a.b --> package.asdf package.a.b // asdf.adsf --> asdf.asdf - const char* p = className.string(); + const char* p = className.c_str(); const char* q = strchr(p, '.'); if (p == q) { className = pkg; @@ -3023,7 +3024,7 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass if (assGroup->getFiles().size() != 1) { fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", - assGroup->getFiles().valueAt(0)->getPrintableSource().string()); + assGroup->getFiles().valueAt(0)->getPrintableSource().c_str()); } assFile = assGroup->getFiles().valueAt(0); @@ -3048,7 +3049,7 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass } depth++; String8 tag(tree.getElementName(&len)); - // printf("Depth %d tag %s\n", depth, tag.string()); + // printf("Depth %d tag %s\n", depth, tag.c_str()); bool keepTag = false; if (depth == 1) { if (tag != "manifest") { @@ -3065,7 +3066,7 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass "http://schemas.android.com/apk/res/android", "backupAgent", &error); if (agent.length() > 0) { - addProguardKeepRule(keep, agent, pkg.string(), + addProguardKeepRule(keep, agent, pkg.c_str(), assFile->getPrintableSource(), tree.getLineNumber()); } @@ -3073,7 +3074,7 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass defaultProcess = AaptXml::getAttribute(tree, "http://schemas.android.com/apk/res/android", "process", &error); if (error != "") { - fprintf(stderr, "ERROR: %s\n", error.string()); + fprintf(stderr, "ERROR: %s\n", error.c_str()); return -1; } } @@ -3089,7 +3090,7 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass String8 componentProcess = AaptXml::getAttribute(tree, "http://schemas.android.com/apk/res/android", "process", &error); if (error != "") { - fprintf(stderr, "ERROR: %s\n", error.string()); + fprintf(stderr, "ERROR: %s\n", error.c_str()); return -1; } @@ -3103,14 +3104,14 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass String8 name = AaptXml::getAttribute(tree, "http://schemas.android.com/apk/res/android", "name", &error); if (error != "") { - fprintf(stderr, "ERROR: %s\n", error.string()); + fprintf(stderr, "ERROR: %s\n", error.c_str()); return -1; } keepTag = name.length() > 0; if (keepTag) { - addProguardKeepRule(keep, name, pkg.string(), + addProguardKeepRule(keep, name, pkg.c_str(), assFile->getPrintableSource(), tree.getLineNumber()); } } @@ -3170,7 +3171,7 @@ writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile, String8 tag(tree.getElementName(&len)); // If there is no '.', we'll assume that it's one of the built in names. - if (strchr(tag.string(), '.')) { + if (strchr(tag.c_str(), '.')) { addProguardKeepRule(keep, tag, NULL, layoutFile->getPrintableSource(), tree.getLineNumber()); } else if (tagAttrPairs != NULL) { @@ -3183,8 +3184,8 @@ writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile, ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr); if (attrIndex < 0) { // fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n", - // layoutFile->getPrintableSource().string(), tree.getLineNumber(), - // tag.string(), nsAttr.ns, nsAttr.attr); + // layoutFile->getPrintableSource().c_str(), tree.getLineNumber(), + // tag.c_str(), nsAttr.ns, nsAttr.attr); } else { size_t len; addProguardKeepRule(keep, @@ -3242,7 +3243,7 @@ writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets) // tag:attribute pairs that should be checked in transition files. KeyedVector<String8, Vector<NamespaceAttributePair> > kTransitionTagAttrPairs; - addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, kClass); + addTagAttrPair(&kTransitionTagAttrPairs, kTransition.c_str(), NULL, kClass); addTagAttrPair(&kTransitionTagAttrPairs, "pathMotion", NULL, kClass); const Vector<sp<AaptDir> >& dirs = assets->resDirs(); @@ -3252,16 +3253,16 @@ writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets) const String8& dirName = d->getLeaf(); Vector<String8> startTags; const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL; - if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) { + if ((dirName == String8("layout")) || (strncmp(dirName.c_str(), "layout-", 7) == 0)) { tagAttrPairs = &kLayoutTagAttrPairs; - } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) { + } else if ((dirName == String8("xml")) || (strncmp(dirName.c_str(), "xml-", 4) == 0)) { startTags.add(String8("PreferenceScreen")); startTags.add(String8("preference-headers")); tagAttrPairs = &kXmlTagAttrPairs; - } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) { + } else if ((dirName == String8("menu")) || (strncmp(dirName.c_str(), "menu-", 5) == 0)) { startTags.add(String8("menu")); tagAttrPairs = NULL; - } else if (dirName == kTransition || (strncmp(dirName.string(), kTransitionPrefix.string(), + } else if (dirName == kTransition || (strncmp(dirName.c_str(), kTransitionPrefix.c_str(), kTransitionPrefix.size()) == 0)) { tagAttrPairs = &kTransitionTagAttrPairs; } else { @@ -3307,9 +3308,9 @@ writeProguardSpec(const char* filename, const ProguardKeepSet& keep, status_t er const SortedVector<String8>& locations = rules.valueAt(i); const size_t M = locations.size(); for (size_t j=0; j<M; j++) { - fprintf(fp, "# %s\n", locations.itemAt(j).string()); + fprintf(fp, "# %s\n", locations.itemAt(j).c_str()); } - fprintf(fp, "%s\n\n", rules.keyAt(i).string()); + fprintf(fp, "%s\n\n", rules.keyAt(i).c_str()); } fclose(fp); @@ -3366,7 +3367,7 @@ status_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp) status_t deps = -1; for (size_t file_i = 0; file_i < files->size(); ++file_i) { // Add the full file path to the dependency file - fprintf(fp, "%s \\\n", files->itemAt(file_i).string()); + fprintf(fp, "%s \\\n", files->itemAt(file_i).c_str()); deps++; } return deps; diff --git a/tools/aapt/ResourceFilter.cpp b/tools/aapt/ResourceFilter.cpp index ed06f605eaeb..cc8dce7e9f3e 100644 --- a/tools/aapt/ResourceFilter.cpp +++ b/tools/aapt/ResourceFilter.cpp @@ -32,7 +32,7 @@ WeakResourceFilter::parse(const String8& str) // only specify locale in the standard 'en_US' format. val.writeTo(&entry.first); } else if (!AaptConfig::parse(part, &entry.first)) { - fprintf(stderr, "Invalid configuration: %s\n", part.string()); + fprintf(stderr, "Invalid configuration: %s\n", part.c_str()); return UNKNOWN_ERROR; } @@ -43,7 +43,7 @@ WeakResourceFilter::parse(const String8& str) // Ignore any densities. Those are best handled in --preferred-density if ((entry.second & ResTable_config::CONFIG_DENSITY) != 0) { - fprintf(stderr, "warning: ignoring flag -c %s. Use --preferred-density instead.\n", entry.first.toString().string()); + fprintf(stderr, "warning: ignoring flag -c %s. Use --preferred-density instead.\n", entry.first.toString().c_str()); entry.first.density = 0; entry.second &= ~ResTable_config::CONFIG_DENSITY; } @@ -148,7 +148,7 @@ StrongResourceFilter::parse(const String8& str) { mConfigs.clear(); for (size_t i = 0; i < configStrs.size(); i++) { if (!AaptConfig::parse(configStrs[i], &config)) { - fprintf(stderr, "Invalid configuration: %s\n", configStrs[i].string()); + fprintf(stderr, "Invalid configuration: %s\n", configStrs[i].c_str()); return UNKNOWN_ERROR; } mConfigs.insert(config); diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp index 8835fb0130a3..1c7788d70053 100644 --- a/tools/aapt/ResourceIdCache.cpp +++ b/tools/aapt/ResourceIdCache.cpp @@ -37,7 +37,7 @@ static inline uint32_t hashround(uint32_t hash, int c) { static uint32_t hash(const android::String16& hashableString) { uint32_t hash = 5381; - const char16_t* str = hashableString.string(); + const char16_t* str = hashableString.c_str(); while (int c = *str++) hash = hashround(hash, c); return hash; } diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 4e597fb3b30a..449e0808806e 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -11,6 +11,7 @@ #include "ResourceFilter.h" #include "ResourceIdCache.h" #include "SdkConstants.h" +#include "Utils.h" #include <algorithm> #include <androidfw/ResourceTypes.h> @@ -361,10 +362,10 @@ static status_t compileAttribute(const sp<AaptFile>& in, ssize_t typeIdx = block.indexOfAttribute(NULL, "format"); if (typeIdx >= 0) { String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len)); - attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags); + attr.type = parse_flags(typeStr.c_str(), typeStr.size(), gFormatFlags); if (attr.type == 0) { attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n", - String8(typeStr).string()); + String8(typeStr).c_str()); attr.hasErrors = true; } attr.createIfNeeded(outTable); @@ -374,14 +375,14 @@ static status_t compileAttribute(const sp<AaptFile>& in, attr.createIfNeeded(outTable); } - //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type); + //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).c_str(), attr.type); ssize_t minIdx = block.indexOfAttribute(NULL, "min"); if (minIdx >= 0) { String16 val = String16(block.getAttributeStringValue(minIdx, &len)); - if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { + if (!ResTable::stringToInt(val.c_str(), val.size(), NULL)) { attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n", - String8(val).string()); + String8(val).c_str()); attr.hasErrors = true; } attr.createIfNeeded(outTable); @@ -397,9 +398,9 @@ static status_t compileAttribute(const sp<AaptFile>& in, ssize_t maxIdx = block.indexOfAttribute(NULL, "max"); if (maxIdx >= 0) { String16 val = String16(block.getAttributeStringValue(maxIdx, &len)); - if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { + if (!ResTable::stringToInt(val.c_str(), val.size(), NULL)) { attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n", - String8(val).string()); + String8(val).c_str()); attr.hasErrors = true; } attr.createIfNeeded(outTable); @@ -422,7 +423,7 @@ static status_t compileAttribute(const sp<AaptFile>& in, uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error); if (error) { attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n", - String8(str).string()); + String8(str).c_str()); attr.hasErrors = true; } attr.createIfNeeded(outTable); @@ -442,14 +443,14 @@ static status_t compileAttribute(const sp<AaptFile>& in, while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::START_TAG) { uint32_t localType = 0; - if (strcmp16(block.getElementName(&len), enum16.string()) == 0) { + if (strcmp16(block.getElementName(&len), enum16.c_str()) == 0) { localType = ResTable_map::TYPE_ENUM; - } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), flag16.c_str()) == 0) { localType = ResTable_map::TYPE_FLAGS; } else { SourcePos(in->getPrintableSource(), block.getLineNumber()) .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n", - String8(block.getElementName(&len)).string()); + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } @@ -505,11 +506,11 @@ static status_t compileAttribute(const sp<AaptFile>& in, .error("A 'value' attribute is required for <enum> or <flag>\n"); attr.hasErrors = true; } - if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) { + if (!attr.hasErrors && !ResTable::stringToInt(value.c_str(), value.size(), NULL)) { SourcePos(in->getPrintableSource(), block.getLineNumber()) .error("Tag <enum> or <flag> 'value' attribute must be a number," " not \"%s\"\n", - String8(value).string()); + String8(value).c_str()); attr.hasErrors = true; } @@ -546,21 +547,21 @@ static status_t compileAttribute(const sp<AaptFile>& in, } } } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { + if (strcmp16(block.getElementName(&len), attr16.c_str()) == 0) { break; } if ((attr.type&ResTable_map::TYPE_ENUM) != 0) { - if (strcmp16(block.getElementName(&len), enum16.string()) != 0) { + if (strcmp16(block.getElementName(&len), enum16.c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()) .error("Found tag </%s> where </enum> is expected\n", - String8(block.getElementName(&len)).string()); + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } } else { - if (strcmp16(block.getElementName(&len), flag16.string()) != 0) { + if (strcmp16(block.getElementName(&len), flag16.c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()) .error("Found tag </%s> where </flag> is expected\n", - String8(block.getElementName(&len)).string()); + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } } @@ -606,7 +607,7 @@ status_t parseAndAddBag(Bundle* bundle, String16 str; Vector<StringPool::entry_style_span> spans; - err = parseStyledString(bundle, in->getPrintableSource().string(), + err = parseStyledString(bundle, in->getPrintableSource().c_str(), block, item16, &str, &spans, isFormatted, pseudolocalize); if (err != NO_ERROR) { @@ -619,10 +620,10 @@ status_t parseAndAddBag(Bundle* bundle, config.language[0], config.language[1], config.country[0], config.country[1], config.orientation, config.density, - String8(parentIdent).string(), - String8(ident).string(), - String8(itemIdent).string(), - String8(str).string()); + String8(parentIdent).c_str(), + String8(ident).c_str(), + String8(itemIdent).c_str(), + String8(str).c_str()); } err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()), @@ -636,8 +637,8 @@ status_t parseAndAddBag(Bundle* bundle, * haystack, false otherwise. */ bool isInProductList(const String16& needle, const String16& haystack) { - const char16_t *needle2 = needle.string(); - const char16_t *haystack2 = haystack.string(); + const char16_t *needle2 = needle.c_str(); + const char16_t *haystack2 = haystack.c_str(); size_t needlesize = needle.size(); while (*haystack2 != '\0') { @@ -703,7 +704,7 @@ status_t parseAndAddEntry(Bundle* bundle, String16 str; Vector<StringPool::entry_style_span> spans; - err = parseStyledString(bundle, in->getPrintableSource().string(), block, + err = parseStyledString(bundle, in->getPrintableSource().c_str(), block, curTag, &str, curIsStyled ? &spans : NULL, isFormatted, pseudolocalize); @@ -730,7 +731,7 @@ status_t parseAndAddEntry(Bundle* bundle, */ if (bundleProduct[0] == '\0') { - if (strcmp16(String16("default").string(), product.string()) != 0) { + if (strcmp16(String16("default").c_str(), product.c_str()) != 0) { /* * This string has a product other than 'default'. Do not add it, * but record it so that if we do not see the same string with @@ -750,7 +751,7 @@ status_t parseAndAddEntry(Bundle* bundle, if (isInProductList(product, String16(bundleProduct))) { ; - } else if (strcmp16(String16("default").string(), product.string()) == 0 && + } else if (strcmp16(String16("default").c_str(), product.c_str()) == 0 && !outTable->hasBagOrEntry(myPackage, curType, ident, config)) { ; } else { @@ -764,7 +765,7 @@ status_t parseAndAddEntry(Bundle* bundle, config.language[0], config.language[1], config.country[0], config.country[1], config.orientation, config.density, - String8(ident).string(), String8(str).string()); + String8(ident).c_str(), String8(str).c_str()); } err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()), @@ -847,7 +848,7 @@ status_t compileResourceFile(Bundle* bundle, bool hasErrors = false; bool fileIsTranslatable = true; - if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) { + if (strstr(in->getPrintableSource().c_str(), "donottranslate") != NULL) { fileIsTranslatable = false; } @@ -869,9 +870,9 @@ status_t compileResourceFile(Bundle* bundle, "No start tag found\n"); return UNKNOWN_ERROR; } - if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { + if (strcmp16(block.getElementName(&len), resources16.c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Invalid start tag %s\n", String8(block.getElementName(&len)).string()); + "Invalid start tag %s\n", String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } @@ -900,7 +901,7 @@ status_t compileResourceFile(Bundle* bundle, SourcePos(in->getPrintableSource(), 0).warning( "Resource file %s is skipped as pseudolocalization" " was done automatically.", - in->getPrintableSource().string()); + in->getPrintableSource().c_str()); return NO_ERROR; } @@ -917,29 +918,29 @@ status_t compileResourceFile(Bundle* bundle, bool curIsFormatted = fileIsTranslatable; bool localHasErrors = false; - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { + if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) { while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { + if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) { while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { + if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), public16.c_str()) == 0) { SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); String16 type; @@ -965,7 +966,7 @@ status_t compileResourceFile(Bundle* bundle, Res_value identValue; if (!ResTable::stringToInt(identStr, len, &identValue)) { srcPos.error("Given 'id' attribute is not an integer: %s\n", - String8(block.getAttributeStringValue(identIdx, &len)).string()); + String8(block.getAttributeStringValue(identIdx, &len)).c_str()); hasErrors = localHasErrors = true; } else { ident = identValue.data; @@ -1004,14 +1005,14 @@ status_t compileResourceFile(Bundle* bundle, while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), public16.string()) == 0) { + if (strcmp16(block.getElementName(&len), public16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), public_padding16.c_str()) == 0) { SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); String16 type; @@ -1037,7 +1038,7 @@ status_t compileResourceFile(Bundle* bundle, Res_value startValue; if (!ResTable::stringToInt(startStr, len, &startValue)) { srcPos.error("Given 'start' attribute is not an integer: %s\n", - String8(block.getAttributeStringValue(startIdx, &len)).string()); + String8(block.getAttributeStringValue(startIdx, &len)).c_str()); hasErrors = localHasErrors = true; } else { start = startValue.data; @@ -1057,7 +1058,7 @@ status_t compileResourceFile(Bundle* bundle, Res_value endValue; if (!ResTable::stringToInt(endStr, len, &endValue)) { srcPos.error("Given 'end' attribute is not an integer: %s\n", - String8(block.getAttributeStringValue(endIdx, &len)).string()); + String8(block.getAttributeStringValue(endIdx, &len)).c_str()); hasErrors = localHasErrors = true; } else { end = endValue.data; @@ -1114,14 +1115,14 @@ status_t compileResourceFile(Bundle* bundle, while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { + if (strcmp16(block.getElementName(&len), public_padding16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), private_symbols16.c_str()) == 0) { String16 pkg; ssize_t pkgIdx = block.indexOfAttribute(NULL, "package"); if (pkgIdx < 0) { @@ -1144,14 +1145,14 @@ status_t compileResourceFile(Bundle* bundle, 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) { + if (strcmp16(block.getElementName(&len), private_symbols16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), java_symbol16.c_str()) == 0) { SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); String16 type; @@ -1186,7 +1187,7 @@ status_t compileResourceFile(Bundle* bundle, while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { + if (strcmp16(block.getElementName(&len), java_symbol16.c_str()) == 0) { break; } } @@ -1194,7 +1195,7 @@ status_t compileResourceFile(Bundle* bundle, continue; - } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), add_resource16.c_str()) == 0) { SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); String16 typeName; @@ -1217,14 +1218,14 @@ status_t compileResourceFile(Bundle* bundle, while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { + if (strcmp16(block.getElementName(&len), add_resource16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), declare_styleable16.c_str()) == 0) { SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); String16 ident; @@ -1258,30 +1259,30 @@ status_t compileResourceFile(Bundle* bundle, while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::START_TAG) { - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { + if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) { while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { + if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) { while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { + if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) { break; } } } continue; - } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) { + } else if (strcmp16(block.getElementName(&len), attr16.c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n", - String8(block.getElementName(&len)).string()); + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } @@ -1297,30 +1298,30 @@ status_t compileResourceFile(Bundle* bundle, SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber()); symbols->addSymbol(String8(itemIdent), 0, srcPos); symbols->appendComment(String8(itemIdent), comment, srcPos); - //printf("Attribute %s comment: %s\n", String8(itemIdent).string(), - // String8(comment).string()); + //printf("Attribute %s comment: %s\n", String8(itemIdent).c_str(), + // String8(comment).c_str()); } } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { + if (strcmp16(block.getElementName(&len), declare_styleable16.c_str()) == 0) { break; } SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Found tag </%s> where </attr> is expected\n", - String8(block.getElementName(&len)).string()); + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } } continue; - } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), attr16.c_str()) == 0) { err = compileAttribute(in, block, myPackage, outTable, NULL); if (err != NO_ERROR) { hasErrors = true; } continue; - } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), item16.c_str()) == 0) { curTag = &item16; ssize_t attri = block.indexOfAttribute(NULL, "type"); if (attri >= 0) { @@ -1333,12 +1334,12 @@ status_t compileResourceFile(Bundle* bundle, if (formatIdx >= 0) { String16 formatStr = String16(block.getAttributeStringValue( formatIdx, &len)); - curFormat = parse_flags(formatStr.string(), formatStr.size(), + curFormat = parse_flags(formatStr.c_str(), formatStr.size(), gFormatFlags); if (curFormat == 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Tag <item> 'format' attribute value \"%s\" not valid\n", - String8(formatStr).string()); + String8(formatStr).c_str()); hasErrors = localHasErrors = true; } } @@ -1348,7 +1349,7 @@ status_t compileResourceFile(Bundle* bundle, hasErrors = localHasErrors = true; } curIsStyled = true; - } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), string16.c_str()) == 0) { // Note the existence and locale of every string we process char rawLocale[RESTABLE_MAX_LOCALE_LEN]; curParams.getBcp47Locale(rawLocale); @@ -1361,11 +1362,11 @@ status_t compileResourceFile(Bundle* bundle, for (size_t i = 0; i < n; i++) { size_t length; const char16_t* attr = block.getAttributeName(i, &length); - if (strcmp16(attr, name16.string()) == 0) { + if (strcmp16(attr, name16.c_str()) == 0) { name.setTo(block.getAttributeStringValue(i, &length)); - } else if (strcmp16(attr, translatable16.string()) == 0) { + } else if (strcmp16(attr, translatable16.c_str()) == 0) { translatable.setTo(block.getAttributeStringValue(i, &length)); - } else if (strcmp16(attr, formatted16.string()) == 0) { + } else if (strcmp16(attr, formatted16.c_str()) == 0) { formatted.setTo(block.getAttributeStringValue(i, &length)); } } @@ -1380,8 +1381,8 @@ status_t compileResourceFile(Bundle* bundle, if (locale.size() > 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( "string '%s' marked untranslatable but exists in locale '%s'\n", - String8(name).string(), - locale.string()); + String8(name).c_str(), + locale.c_str()); // hasErrors = localHasErrors = true; } else { // Intentionally empty block: @@ -1407,31 +1408,31 @@ status_t compileResourceFile(Bundle* bundle, curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; curIsStyled = true; curIsPseudolocalizable = fileIsTranslatable && (translatable != false16); - } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), drawable16.c_str()) == 0) { curTag = &drawable16; curType = drawable16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; - } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), color16.c_str()) == 0) { curTag = &color16; curType = color16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; - } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), bool16.c_str()) == 0) { curTag = &bool16; curType = bool16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN; - } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), integer16.c_str()) == 0) { curTag = &integer16; curType = integer16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; - } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), dimen16.c_str()) == 0) { curTag = &dimen16; curType = dimen16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION; - } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), fraction16.c_str()) == 0) { curTag = &fraction16; curType = fraction16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION; - } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), bag16.c_str()) == 0) { curTag = &bag16; curIsBag = true; ssize_t attri = block.indexOfAttribute(NULL, "type"); @@ -1442,16 +1443,16 @@ status_t compileResourceFile(Bundle* bundle, "A 'type' attribute is required for <bag>\n"); hasErrors = localHasErrors = true; } - } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), style16.c_str()) == 0) { curTag = &style16; curType = style16; curIsBag = true; - } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), plurals16.c_str()) == 0) { curTag = &plurals16; curType = plurals16; curIsBag = true; curIsPseudolocalizable = fileIsTranslatable; - } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), array16.c_str()) == 0) { curTag = &array16; curType = array16; curIsBag = true; @@ -1460,16 +1461,16 @@ status_t compileResourceFile(Bundle* bundle, if (formatIdx >= 0) { String16 formatStr = String16(block.getAttributeStringValue( formatIdx, &len)); - curFormat = parse_flags(formatStr.string(), formatStr.size(), + curFormat = parse_flags(formatStr.c_str(), formatStr.size(), gFormatFlags); if (curFormat == 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Tag <array> 'format' attribute value \"%s\" not valid\n", - String8(formatStr).string()); + String8(formatStr).c_str()); hasErrors = localHasErrors = true; } } - } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), string_array16.c_str()) == 0) { // Check whether these strings need valid formats. // (simplified form of what string16 does above) bool isTranslatable = false; @@ -1480,14 +1481,14 @@ status_t compileResourceFile(Bundle* bundle, for (size_t i = 0; i < n; i++) { size_t length; const char16_t* attr = block.getAttributeName(i, &length); - if (strcmp16(attr, formatted16.string()) == 0) { + if (strcmp16(attr, formatted16.c_str()) == 0) { const char16_t* value = block.getAttributeStringValue(i, &length); - if (strcmp16(value, false16.string()) == 0) { + if (strcmp16(value, false16.c_str()) == 0) { curIsFormatted = false; } - } else if (strcmp16(attr, translatable16.string()) == 0) { + } else if (strcmp16(attr, translatable16.c_str()) == 0) { const char16_t* value = block.getAttributeStringValue(i, &length); - if (strcmp16(value, false16.string()) == 0) { + if (strcmp16(value, false16.c_str()) == 0) { isTranslatable = false; } } @@ -1499,7 +1500,7 @@ status_t compileResourceFile(Bundle* bundle, curIsBag = true; curIsBagReplaceOnOverwrite = true; curIsPseudolocalizable = isTranslatable && fileIsTranslatable; - } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) { + } else if (strcmp16(block.getElementName(&len), integer_array16.c_str()) == 0) { curTag = &integer_array16; curType = array16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; @@ -1508,7 +1509,7 @@ status_t compileResourceFile(Bundle* bundle, } else { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Found tag %s where item is expected\n", - String8(block.getElementName(&len)).string()); + String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } @@ -1519,7 +1520,7 @@ status_t compileResourceFile(Bundle* bundle, } else { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "A 'name' attribute is required for <%s>\n", - String8(*curTag).string()); + String8(*curTag).c_str()); hasErrors = localHasErrors = true; } @@ -1560,11 +1561,11 @@ status_t compileResourceFile(Bundle* bundle, && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::START_TAG) { - if (strcmp16(block.getElementName(&len), item16.string()) != 0) { + if (strcmp16(block.getElementName(&len), item16.c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Tag <%s> can not appear inside <%s>, only <item>\n", - String8(block.getElementName(&len)).string(), - String8(*curTag).string()); + String8(block.getElementName(&len)).c_str(), + String8(*curTag).c_str()); return UNKNOWN_ERROR; } @@ -1647,11 +1648,11 @@ status_t compileResourceFile(Bundle* bundle, hasErrors = localHasErrors = true; } } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), curTag->string()) != 0) { + if (strcmp16(block.getElementName(&len), curTag->c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Found tag </%s> where </%s> is expected\n", - String8(block.getElementName(&len)).string(), - String8(*curTag).string()); + String8(block.getElementName(&len)).c_str(), + String8(*curTag).c_str()); return UNKNOWN_ERROR; } break; @@ -1700,9 +1701,9 @@ status_t compileResourceFile(Bundle* bundle, #if 0 if (comment.size() > 0) { - printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(), - String8(curType).string(), String8(ident).string(), - String8(comment).string()); + printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).c_str(), + String8(curType).c_str(), String8(ident).c_str(), + String8(comment).c_str()); } #endif if (!localHasErrors) { @@ -1710,9 +1711,9 @@ status_t compileResourceFile(Bundle* bundle, } } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { + if (strcmp16(block.getElementName(&len), resources16.c_str()) != 0) { SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Unexpected end tag %s\n", String8(block.getElementName(&len)).string()); + "Unexpected end tag %s\n", String8(block.getElementName(&len)).c_str()); return UNKNOWN_ERROR; } } @@ -1724,7 +1725,7 @@ status_t compileResourceFile(Bundle* bundle, } SourcePos(in->getPrintableSource(), block.getLineNumber()).error( "Found text \"%s\" where item tag is expected\n", - String8(block.getText(&len)).string()); + String8(block.getText(&len)).c_str()); return UNKNOWN_ERROR; } } @@ -1740,13 +1741,13 @@ status_t compileResourceFile(Bundle* bundle, const char* bundleProduct = (bundle->getProduct() == NULL) ? "" : bundle->getProduct(); fprintf(stderr, "In resource file %s: %s\n", - in->getPrintableSource().string(), - curParams.toString().string()); + in->getPrintableSource().c_str(), + curParams.toString().c_str()); fprintf(stderr, "\t%s '%s' does not match product %s.\n" "\tYou may have forgotten to include a 'default' product variant" " of the resource.\n", - String8(p.type).string(), String8(p.ident).string(), + String8(p.type).c_str(), String8(p.ident).c_str(), bundleProduct[0] == 0 ? "default" : bundleProduct); return UNKNOWN_ERROR; } @@ -1816,7 +1817,7 @@ status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets AssetManager featureAssetManager; if (!featureAssetManager.addAssetPath(featureAfter, NULL)) { fprintf(stderr, "ERROR: Feature package '%s' not found.\n", - featureAfter.string()); + featureAfter.c_str()); return UNKNOWN_ERROR; } @@ -1835,13 +1836,13 @@ status_t ResourceTable::addPublic(const SourcePos& sourcePos, const uint32_t ident) { uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size()); if (rid != 0) { sourcePos.error("Error declaring public resource %s/%s for included package %s\n", - String8(type).string(), String8(name).string(), - String8(package).string()); + String8(type).c_str(), String8(name).c_str(), + String8(package).c_str()); return UNKNOWN_ERROR; } @@ -1864,12 +1865,12 @@ status_t ResourceTable::addEntry(const SourcePos& sourcePos, const bool overwrite) { uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size()); if (rid != 0) { sourcePos.error("Resource entry %s/%s is already defined in package %s.", - String8(type).string(), String8(name).string(), String8(package).string()); + String8(type).c_str(), String8(name).c_str(), String8(package).c_str()); return UNKNOWN_ERROR; } @@ -1899,12 +1900,12 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos, // 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()); + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size()); if (rid != 0) { sourcePos.error("Resource entry %s/%s is already defined in package %s.", - String8(type).string(), String8(name).string(), String8(package).string()); + String8(type).c_str(), String8(name).c_str(), String8(package).c_str()); return UNKNOWN_ERROR; } @@ -1921,7 +1922,7 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos, } if (!canAdd) { sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n", - String8(name).string()); + String8(name).c_str()); return UNKNOWN_ERROR; } } @@ -1959,9 +1960,9 @@ status_t ResourceTable::addBag(const SourcePos& sourcePos, // 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()); + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size()); if (rid != 0) { return NO_ERROR; } @@ -1969,7 +1970,7 @@ status_t ResourceTable::addBag(const SourcePos& sourcePos, #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.file.striing(), sourcePos.line, String8(type).c_str()); } #endif sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params); @@ -1996,9 +1997,9 @@ bool ResourceTable::hasBagOrEntry(const String16& package, { // First look for this in the included resources... uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size()); if (rid != 0) { return true; } @@ -2022,9 +2023,9 @@ bool ResourceTable::hasBagOrEntry(const String16& package, { // First look for this in the included resources... uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size()); if (rid != 0) { return true; } @@ -2051,7 +2052,7 @@ bool ResourceTable::hasBagOrEntry(const String16& ref, const String16* defPackage) { String16 package, type, name; - if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name, + if (!ResTable::expandResourceRef(ref.c_str(), ref.size(), &package, &type, &name, defType, defPackage ? defPackage:&mAssetsPackage, NULL)) { return false; } @@ -2115,17 +2116,17 @@ bool ResourceTable::makeAttribute(const String16& package, // First look for this in the included resources... uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - attr16.string(), attr16.size(), - package.string(), package.size()); + .identifierForName(name.c_str(), name.size(), + attr16.c_str(), attr16.size(), + package.c_str(), package.size()); if (rid != 0) { - source.error("Attribute \"%s\" has already been defined", String8(name).string()); + source.error("Attribute \"%s\" has already been defined", String8(name).c_str()); return false; } sp<ResourceTable::Entry> entry = getEntry(package, attr16, name, source, false); if (entry == NULL) { - source.error("Failed to create entry attr/%s", String8(name).string()); + source.error("Failed to create entry attr/%s", String8(name).c_str()); return false; } @@ -2146,7 +2147,7 @@ bool ResourceTable::makeAttribute(const String16& package, formatItem.value != formatValue16) { source.error("Attribute \"%s\" already defined with incompatible format.\n" "%s:%d: Original attribute defined here.", - String8(name).string(), formatItem.sourcePos.file.string(), + String8(name).c_str(), formatItem.sourcePos.file.c_str(), formatItem.sourcePos.line); return false; } @@ -2207,9 +2208,9 @@ uint32_t ResourceTable::getResId(const String16& package, // First look for this in the included resources... uint32_t specFlags = 0; uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size(), + .identifierForName(name.c_str(), name.size(), + type.c_str(), type.size(), + package.c_str(), package.size(), &specFlags); if (rid != 0) { if (onlyPublic && (specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { @@ -2253,27 +2254,27 @@ uint32_t ResourceTable::getResId(const String16& ref, String16 package, type, name; bool refOnlyPublic = true; if (!ResTable::expandResourceRef( - ref.string(), ref.size(), &package, &type, &name, + ref.c_str(), ref.size(), &package, &type, &name, defType, defPackage ? defPackage:&mAssetsPackage, outErrorMsg, &refOnlyPublic)) { if (kIsDebug) { - printf("Expanding resource: ref=%s\n", String8(ref).string()); + printf("Expanding resource: ref=%s\n", String8(ref).c_str()); printf("Expanding resource: defType=%s\n", - defType ? String8(*defType).string() : "NULL"); + defType ? String8(*defType).c_str() : "NULL"); printf("Expanding resource: defPackage=%s\n", - defPackage ? String8(*defPackage).string() : "NULL"); - printf("Expanding resource: ref=%s\n", String8(ref).string()); + defPackage ? String8(*defPackage).c_str() : "NULL"); + printf("Expanding resource: ref=%s\n", String8(ref).c_str()); printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n", - String8(package).string(), String8(type).string(), - String8(name).string()); + String8(package).c_str(), String8(type).c_str(), + String8(name).c_str()); } return 0; } uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic); if (kIsDebug) { printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", - String8(package).string(), String8(type).string(), - String8(name).string(), res); + String8(package).c_str(), String8(type).c_str(), + String8(name).c_str(), res); } if (res == 0) { if (outErrorMsg) @@ -2284,7 +2285,7 @@ uint32_t ResourceTable::getResId(const String16& ref, bool ResourceTable::isValidResourceName(const String16& s) { - const char16_t* p = s.string(); + const char16_t* p = s.c_str(); bool first = true; while (*p) { if ((*p >= 'a' && *p <= 'z') @@ -2315,7 +2316,7 @@ bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, if (style == NULL || style->size() == 0) { // Text is not styled so it can be any type... let's figure it out. res = mAssets->getIncludedResources() - .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces, + .stringToValue(outValue, &finalStr, str.c_str(), str.size(), preserveSpaces, coerceType, attrID, NULL, &mAssetsPackage, this, accessorCookie, attrType); } else { @@ -2344,7 +2345,7 @@ bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, if (kIsDebug) { printf("Adding to pool string style #%zu config %s: %s\n", style != NULL ? style->size() : 0U, - configStr.string(), String8(finalStr).string()); + configStr.c_str(), String8(finalStr).c_str()); } if (style != NULL && style->size() > 0) { outValue->data = pool->add(finalStr, *style, configTypeName, config); @@ -2368,8 +2369,8 @@ bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, uint32_t ResourceTable::getCustomResource( const String16& package, const String16& type, const String16& name) const { - //printf("getCustomResource: %s %s %s\n", String8(package).string(), - // String8(type).string(), String8(name).string()); + //printf("getCustomResource: %s %s %s\n", String8(package).c_str(), + // String8(type).c_str(), String8(name).c_str()); sp<Package> p = mPackages.valueFor(package); if (p == NULL) return 0; sp<Type> t = p->getTypes().valueFor(type); @@ -2400,7 +2401,7 @@ uint32_t ResourceTable::getCustomResourceWithCreation( if (mAssetsPackage != package) { mCurrentXmlPos.error("creating resource for external package %s: %s/%s.", - String8(package).string(), String8(type).string(), String8(name).string()); + String8(package).c_str(), String8(type).c_str(), String8(name).c_str()); if (package == String16("android")) { mCurrentXmlPos.printf("did you mean to use @+id instead of @+android:id?"); } @@ -2427,7 +2428,7 @@ bool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType) Res_value value; if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) { //printf("getAttributeType #%08x (%s): #%08x\n", attrID, - // String8(getEntry(attrID)->getName()).string(), value.data); + // String8(getEntry(attrID)->getName()).c_str(), value.data); *outType = value.data; return true; } @@ -2481,7 +2482,7 @@ void ResourceTable::reportError(void* accessorCookie, const char* fmt, ...) vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n", - buf, ac->attr.string(), ac->value.string()); + buf, ac->attr.c_str(), ac->value.c_str()); } } @@ -2493,7 +2494,7 @@ bool ResourceTable::getAttributeKeys( const size_t N = e->getBag().size(); for (size_t i=0; i<N; i++) { const String16& key = e->getBag().keyAt(i); - if (key.size() > 0 && key.string()[0] != '^') { + if (key.size() > 0 && key.c_str()[0] != '^') { outKeys->add(key); } } @@ -2506,14 +2507,14 @@ bool ResourceTable::getAttributeEnum( uint32_t attrID, const char16_t* name, size_t nameLen, Res_value* outValue) { - //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string()); + //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).c_str()); String16 nameStr(name, nameLen); sp<const Entry> e = getEntry(attrID); if (e != NULL) { const size_t N = e->getBag().size(); for (size_t i=0; i<N; i++) { - //printf("Comparing %s to %s\n", String8(name, nameLen).string(), - // String8(e->getBag().keyAt(i)).string()); + //printf("Comparing %s to %s\n", String8(name, nameLen).c_str(), + // String8(e->getBag().keyAt(i)).c_str()); if (e->getBag().keyAt(i) == nameStr) { return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue); } @@ -2529,7 +2530,7 @@ bool ResourceTable::getAttributeFlags( outValue->dataType = Res_value::TYPE_INT_HEX; outValue->data = 0; - //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string()); + //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).c_str()); String16 nameStr(name, nameLen); sp<const Entry> e = getEntry(attrID); if (e != NULL) { @@ -2546,8 +2547,8 @@ bool ResourceTable::getAttributeFlags( String16 nameStr(start, pos-start); size_t i; for (i=0; i<N; i++) { - //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(), - // String8(e->getBag().keyAt(i)).string()); + //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).c_str(), + // String8(e->getBag().keyAt(i)).c_str()); if (e->getBag().keyAt(i) == nameStr) { Res_value val; bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val); @@ -2753,7 +2754,7 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols, if (mHasDefaultLocalization.find(c->getName()) == mHasDefaultLocalization.end()) { // printf("Skip symbol [%08x] %s\n", rid, - // String8(c->getName()).string()); + // String8(c->getName()).c_str()); continue; } } @@ -2763,7 +2764,7 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols, String16 comment(c->getComment()); typeSymbols->appendComment(String8(c->getName()), comment, c->getPos()); //printf("Type symbol [%08x] %s comment: %s\n", rid, - // String8(c->getName()).string(), String8(comment).string()); + // String8(c->getName()).c_str(), String8(comment).c_str()); comment = c->getTypeComment(); typeSymbols->appendTypeComment(String8(c->getName()), comment); } @@ -2809,10 +2810,10 @@ ResourceTable::validateLocalizations(void) // Look for strings with no default localization if (configSrcMap.count(defaultLocale) == 0) { SourcePos().warning("string '%s' has no default translation.", - String8(nameIter.first).string()); + String8(nameIter.first).c_str()); if (mBundle->getVerbose()) { for (const auto& locale : configSrcMap) { - locale.second.printf("locale %s found", locale.first.string()); + locale.second.printf("locale %s found", locale.first.c_str()); } } // !!! TODO: throw an error here in some circumstances @@ -2820,7 +2821,7 @@ ResourceTable::validateLocalizations(void) // Check that all requested localizations are present for this string if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) { - const char* allConfigs = mBundle->getConfigurations().string(); + const char* allConfigs = mBundle->getConfigurations().c_str(); const char* start = allConfigs; const char* comma; @@ -2847,7 +2848,7 @@ ResourceTable::validateLocalizations(void) // requiring a specific regional localization [e.g. de_DE] but there is an // available string in the generic language localization [e.g. de]; // consider that string to have fulfilled the localization requirement. - String8 region(config.string(), 2); + String8 region(config.c_str(), 2); if (configSrcMap.find(region) == configSrcMap.end() && configSrcMap.count(defaultLocale) == 0) { missingConfigs.insert(config); @@ -2859,12 +2860,12 @@ ResourceTable::validateLocalizations(void) if (!missingConfigs.empty()) { String8 configStr; for (const auto& iter : missingConfigs) { - configStr.appendFormat(" %s", iter.string()); + configStr.appendFormat(" %s", iter.c_str()); } SourcePos().warning("string '%s' is missing %u required localizations:%s", - String8(nameIter.first).string(), + String8(nameIter.first).c_str(), (unsigned int)missingConfigs.size(), - configStr.string()); + configStr.c_str()); } } } @@ -3021,7 +3022,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& header->header.type = htods(RES_TABLE_PACKAGE_TYPE); header->header.headerSize = htods(sizeof(*header)); header->id = htodl(static_cast<uint32_t>(p->getAssignedId())); - strcpy16_htod(header->name, p->getName().string()); + strcpy16_htod(header->name, p->getName().c_str()); // Write the string blocks. const size_t typeStringsStart = data->getSize(); @@ -3061,7 +3062,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& sp<Type> t = p->getTypes().valueFor(typeName); LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"), "Type name %s not found", - String8(typeName).string()); + String8(typeName).c_str()); if (t == NULL) { continue; } @@ -3260,7 +3261,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); if (c != NULL) { fprintf(stderr, "%s: no entries written for %s/%s (0x%08zx)\n", log_prefix, - String8(typeName).string(), String8(c->getName()).string(), + String8(typeName).c_str(), String8(c->getName()).c_str(), Res_MAKEID(p->getAssignedId() - 1, ti, i)); } missing_entry = true; @@ -3359,7 +3360,7 @@ status_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vect sp<Package> libPackage = libs[i]; if (kIsDebug) { fprintf(stderr, " Entry %s -> 0x%02x\n", - String8(libPackage->getName()).string(), + String8(libPackage->getName()).c_str(), (uint8_t)libPackage->getAssignedId()); } @@ -3367,7 +3368,7 @@ status_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vect entryStart, sizeof(ResTable_lib_entry)); memset(entry, 0, sizeof(*entry)); entry->packageId = htodl(libPackage->getAssignedId()); - strcpy16_htod(entry->packageName, libPackage->getName().string()); + strcpy16_htod(entry->packageName, libPackage->getName().c_str()); } } return NO_ERROR; @@ -3435,13 +3436,13 @@ void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bo const SourcePos& pos = c->getEntries().valueAt(k)->getPos(); if (pos.file != "") { fprintf(fp," <!-- Declared at %s:%d -->\n", - pos.file.string(), pos.line); + pos.file.c_str(), pos.line); } } } fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n", - String8(t->getName()).string(), - String8(c->getName()).string(), + String8(t->getName()).c_str(), + String8(c->getName()).c_str(), getResId(pkg, t, c->getEntryIndex())); } } @@ -3501,8 +3502,8 @@ status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos) } sourcePos.error("Resource entry %s is already defined as a single item.\n" "%s:%d: Originally defined here.\n", - String8(mName).string(), - mItem.sourcePos.file.string(), mItem.sourcePos.line); + String8(mName).c_str(), + mItem.sourcePos.file.c_str(), mItem.sourcePos.line); return UNKNOWN_ERROR; } @@ -3517,21 +3518,21 @@ status_t ResourceTable::Entry::setItem(const SourcePos& sourcePos, if (mType == TYPE_BAG) { if (mBag.size() == 0) { sourcePos.error("Resource entry %s is already defined as a bag.", - String8(mName).string()); + String8(mName).c_str()); } else { const Item& item(mBag.valueAt(0)); sourcePos.error("Resource entry %s is already defined as a bag.\n" "%s:%d: Originally defined here.\n", - String8(mName).string(), - item.sourcePos.file.string(), item.sourcePos.line); + String8(mName).c_str(), + item.sourcePos.file.c_str(), item.sourcePos.line); } return UNKNOWN_ERROR; } if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) { sourcePos.error("Resource entry %s is already defined.\n" "%s:%d: Originally defined here.\n", - String8(mName).string(), - mItem.sourcePos.file.string(), mItem.sourcePos.line); + String8(mName).c_str(), + mItem.sourcePos.file.c_str(), mItem.sourcePos.line); return UNKNOWN_ERROR; } @@ -3562,12 +3563,12 @@ status_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos, const Item& item(mBag.valueAt(origKey)); sourcePos.error("Resource entry %s already has bag item %s.\n" "%s:%d: Originally defined here.\n", - String8(mName).string(), String8(key).string(), - item.sourcePos.file.string(), item.sourcePos.line); + String8(mName).c_str(), String8(key).c_str(), + item.sourcePos.file.c_str(), item.sourcePos.line); return UNKNOWN_ERROR; } //printf("Replacing %s with %s\n", - // String8(mBag.valueFor(key).value).string(), String8(value).string()); + // String8(mBag.valueFor(key).value).c_str(), String8(value).c_str()); mBag.replaceValueFor(key, item); } @@ -3611,8 +3612,8 @@ status_t ResourceTable::Entry::generateAttributes(ResourceTable* table, String16 value("false"); if (kIsDebug) { fprintf(stderr, "Generating %s:id/%s\n", - String8(package).string(), - String8(key).string()); + String8(package).c_str(), + String8(key).c_str()); } status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package, id16, key, value); @@ -3624,10 +3625,10 @@ status_t ResourceTable::Entry::generateAttributes(ResourceTable* table, #if 1 // fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n", -// String8(key).string()); +// String8(key).c_str()); // const Item& item(mBag.valueAt(i)); // fprintf(stderr, "Referenced from file %s line %d\n", -// item.sourcePos.file.string(), item.sourcePos.line); +// item.sourcePos.file.c_str(), item.sourcePos.line); // return UNKNOWN_ERROR; #else char numberStr[16]; @@ -3660,7 +3661,7 @@ status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, mParentId = table->getResId(mParent, &style16, NULL, &errorMsg); if (mParentId == 0) { mPos.error("Error retrieving parent for item: %s '%s'.\n", - errorMsg, String8(mParent).string()); + errorMsg, String8(mParent).c_str()); hasErrors = true; } } @@ -3670,11 +3671,11 @@ status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, Item& it = mBag.editValueAt(i); it.bagKeyId = table->getResId(key, it.isId ? &id16 : &attr16, NULL, &errorMsg); - //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId); + //printf("Bag key of %s: #%08x\n", String8(key).c_str(), it.bagKeyId); if (it.bagKeyId == 0) { it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg, - String8(it.isId ? id16 : attr16).string(), - String8(key).string()); + String8(it.isId ? id16 : attr16).c_str(), + String8(key).c_str()); hasErrors = true; } } @@ -3709,7 +3710,7 @@ status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable } } else { mPos.error("Error: entry %s is not a single item or a bag.\n", - String8(mName).string()); + String8(mName).c_str()); return UNKNOWN_ERROR; } return NO_ERROR; @@ -3732,7 +3733,7 @@ status_t ResourceTable::Entry::remapStringValue(StringPool* strings) } } else { mPos.error("Error: entry %s is not a single item or a bag.\n", - String8(mName).string()); + String8(mName).c_str()); return UNKNOWN_ERROR; } return NO_ERROR; @@ -3768,7 +3769,7 @@ ssize_t ResourceTable::Entry::flatten(Bundle* /* bundle */, const sp<AaptFile>& par.data = htodl(it.parsedValue.data); #if 0 printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n", - String8(mName).string(), it.parsedValue.dataType, + String8(mName).c_str(), it.parsedValue.dataType, it.parsedValue.data, par.res0); #endif err = data->writeData(&par, it.parsedValue.size); @@ -3852,7 +3853,7 @@ status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, int32_t entryIdx = Res_GETENTRY(ident); if (entryIdx < 0) { sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n", - String8(mName).string(), String8(name).string(), ident); + String8(mName).c_str(), String8(name).c_str(), ident); return UNKNOWN_ERROR; } #endif @@ -3863,7 +3864,7 @@ status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, if (mPublicIndex > 0 && mPublicIndex != typeIdx) { sourcePos.error("Public resource %s/%s has conflicting type codes for its" " public identifiers (0x%x vs 0x%x).\n", - String8(mName).string(), String8(name).string(), + String8(mName).c_str(), String8(name).c_str(), mPublicIndex, typeIdx); return UNKNOWN_ERROR; } @@ -3882,8 +3883,8 @@ status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, sourcePos.error("Public resource %s/%s has conflicting public identifiers" " (0x%08x vs 0x%08x).\n" "%s:%d: Originally defined here.\n", - String8(mName).string(), String8(name).string(), p.ident, ident, - p.sourcePos.file.string(), p.sourcePos.line); + String8(mName).c_str(), String8(name).c_str(), p.ident, ident, + p.sourcePos.file.c_str(), p.sourcePos.line); return UNKNOWN_ERROR; } } @@ -3909,7 +3910,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, if (overlay && !autoAddOverlay && 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()); + String8(entry).c_str()); return NULL; } c = new ConfigList(entry, sourcePos); @@ -3931,7 +3932,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " "sw%ddp w%ddp h%ddp layout:%d\n", - sourcePos.file.string(), sourcePos.line, + sourcePos.file.c_str(), sourcePos.line, config->mcc, config->mnc, config->language[0] ? config->language[0] : '-', config->language[1] ? config->language[1] : '-', @@ -3951,7 +3952,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, config->screenLayout); } else { printf("New entry at %s:%d: NULL config\n", - sourcePos.file.string(), sourcePos.line); + sourcePos.file.c_str(), sourcePos.line); } } e = new Entry(entry, sourcePos); @@ -4032,11 +4033,11 @@ status_t ResourceTable::Type::applyPublicEntryOrder() const Public& p = mPublic.valueAt(j); int32_t idx = Res_GETENTRY(p.ident); //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n", - // String8(mName).string(), String8(name).string(), p.ident, N); + // String8(mName).c_str(), String8(name).c_str(), p.ident, N); bool found = false; for (i=0; i<N; i++) { sp<ConfigList> e = origOrder.itemAt(i); - //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); + //printf("#%d: \"%s\"\n", i, String8(e->getName()).c_str()); if (e->getName() == name) { if (idx >= (int32_t)mOrderedConfigs.size()) { mOrderedConfigs.resize(idx + 1); @@ -4056,10 +4057,10 @@ status_t ResourceTable::Type::applyPublicEntryOrder() p.sourcePos.error("Multiple entry names declared for public entry" " identifier 0x%x in type %s (%s vs %s).\n" "%s:%d: Originally defined here.", - idx+1, String8(mName).string(), - String8(oe->getName()).string(), - String8(name).string(), - oe->getPublicSourcePos().file.string(), + idx+1, String8(mName).c_str(), + String8(oe->getName()).c_str(), + String8(name).c_str(), + oe->getPublicSourcePos().file.c_str(), oe->getPublicSourcePos().line); hasError = true; } @@ -4068,7 +4069,7 @@ status_t ResourceTable::Type::applyPublicEntryOrder() if (!found) { p.sourcePos.error("Public symbol %s/%s declared here is not defined.", - String8(mName).string(), String8(name).string()); + String8(mName).c_str(), String8(name).c_str()); hasError = true; } } @@ -4189,9 +4190,9 @@ status_t ResourceTable::Package::applyPublicTypeOrder() t->getFirstPublicSourcePos().error("Multiple type names declared for public type" " identifier 0x%x (%s vs %s).\n" "%s:%d: Originally defined here.", - idx, String8(ot->getName()).string(), - String8(t->getName()).string(), - ot->getFirstPublicSourcePos().file.string(), + idx, String8(ot->getName()).c_str(), + String8(t->getName()).c_str(), + ot->getFirstPublicSourcePos().file.c_str(), ot->getFirstPublicSourcePos().line); return UNKNOWN_ERROR; } @@ -4399,8 +4400,8 @@ const ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrI const Item& it = e->getBag().valueAt(i); if (it.bagKeyId == 0) { fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n", - String8(e->getName()).string(), - String8(e->getBag().keyAt(i)).string()); + String8(e->getName()).c_str(), + String8(e->getBag().keyAt(i)).c_str()); } if (it.bagKeyId == attrID) { return ⁢ @@ -4427,8 +4428,8 @@ bool ResourceTable::getItemValue( } } fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n", - String8(e->getName()).string(), - String8(e->getBag().keyAt(i)).string()); + String8(e->getName()).c_str(), + String8(e->getBag().keyAt(i)).c_str()); return false; } item->evaluating = true; @@ -4436,7 +4437,7 @@ bool ResourceTable::getItemValue( if (kIsDebug) { if (res) { printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n", - resID, attrID, String8(getEntry(resID)->getName()).string(), + resID, attrID, String8(getEntry(resID)->getName()).c_str(), outValue->dataType, outValue->data); } else { printf("getItemValue of #%08x[#%08x]: failed\n", @@ -4713,10 +4714,10 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { entriesToAdd[i].value->getPos() .printf("using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", entriesToAdd[i].key.sdkVersion, - String8(p->getName()).string(), - String8(t->getName()).string(), - String8(entriesToAdd[i].value->getName()).string(), - entriesToAdd[i].key.toString().string()); + String8(p->getName()).c_str(), + String8(t->getName()).c_str(), + String8(entriesToAdd[i].value->getName()).c_str(), + entriesToAdd[i].key.toString().c_str()); } sp<Entry> newEntry = t->getEntry(c->getName(), @@ -4801,9 +4802,9 @@ bool ResourceTable::versionForCompat(const Bundle* bundle, const String16& resou sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), AaptGroupEntry(newConfig), target->getResourceType()); String8 resPath = String8::format("res/%s/%s.xml", - newFile->getGroupEntry().toDirName(target->getResourceType()).string(), - String8(resourceName).string()); - resPath.convertToResPath(); + newFile->getGroupEntry().toDirName(target->getResourceType()).c_str(), + String8(resourceName).c_str()); + convertToResPath(resPath); // Add a resource table entry. addEntry(SourcePos(), @@ -4893,10 +4894,10 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, if (bundle->getVerbose()) { SourcePos(node->getFilename(), node->getStartLineNumber()).printf( "removing attribute %s%s%s from <%s>", - String8(attr.ns).string(), + String8(attr.ns).c_str(), (attr.ns.size() == 0 ? "" : ":"), - String8(attr.name).string(), - String8(node->getElementName()).string()); + String8(attr.name).c_str(), + String8(node->getElementName()).c_str()); } node->removeAttribute(i); i--; @@ -4925,19 +4926,19 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), AaptGroupEntry(newConfig), target->getResourceType()); String8 resPath = String8::format("res/%s/%s.xml", - newFile->getGroupEntry().toDirName(target->getResourceType()).string(), - String8(resourceName).string()); - resPath.convertToResPath(); + newFile->getGroupEntry().toDirName(target->getResourceType()).c_str(), + String8(resourceName).c_str()); + convertToResPath(resPath); // Add a resource table entry. if (bundle->getVerbose()) { SourcePos(target->getSourceFile(), -1).printf( "using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", newConfig.sdkVersion, - mAssets->getPackage().string(), - newFile->getResourceType().string(), - String8(resourceName).string(), - newConfig.toString().string()); + mAssets->getPackage().c_str(), + newFile->getResourceType().c_str(), + String8(resourceName).c_str(), + newConfig.toString().c_str()); } addEntry(SourcePos(), @@ -5114,8 +5115,8 @@ status_t ResourceTable::processBundleFormatImpl(const Bundle* bundle, 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()); + String8(child->getElementNamespace()).c_str(), + String8(child->getElementName()).c_str()); return UNKNOWN_ERROR; } @@ -5130,7 +5131,7 @@ status_t ResourceTable::processBundleFormatImpl(const Bundle* bundle, // Parse the attribute name. const char* errorMsg = NULL; String16 attrPackage, attrType, attrName; - bool result = ResTable::expandResourceRef(attr->string.string(), + bool result = ResTable::expandResourceRef(attr->string.c_str(), attr->string.size(), &attrPackage, &attrType, &attrName, &kAttr16, &kAssetPackage16, @@ -5156,11 +5157,11 @@ status_t ResourceTable::processBundleFormatImpl(const Bundle* bundle, // 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++); + String8(resourceName).c_str(), suffix++); nestedResourcePath = String8::format("res/%s/%s.xml", target->getGroupEntry().toDirName(target->getResourceType()) - .string(), - nestedResourceName.string()); + .c_str(), + nestedResourceName.c_str()); // Lookup or create the entry for this name. sp<Entry> entry = getEntry(kAssetPackage16, @@ -5187,20 +5188,20 @@ status_t ResourceTable::processBundleFormatImpl(const Bundle* bundle, if (bundle->getVerbose()) { source.printf("generating nested resource %s:%s/%s", - mAssets->getPackage().string(), target->getResourceType().string(), - nestedResourceName.string()); + mAssets->getPackage().c_str(), target->getResourceType().c_str(), + nestedResourceName.c_str()); } // 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())); + mAssets->getPackage().c_str(), target->getResourceType().c_str(), + nestedResourceName.c_str())); 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()); + String8(attrPackage).c_str(), String8(attrName).c_str()); return UNKNOWN_ERROR; } diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp index 38643201c22d..e13028684414 100644 --- a/tools/aapt/SourcePos.cpp +++ b/tools/aapt/SourcePos.cpp @@ -80,12 +80,12 @@ ErrorPos::print(FILE* to) const if (!this->file.isEmpty()) { if (this->line >= 0) { - fprintf(to, "%s:%d: %s%s\n", this->file.string(), this->line, type, this->error.string()); + fprintf(to, "%s:%d: %s%s\n", this->file.c_str(), this->line, type, this->error.c_str()); } else { - fprintf(to, "%s: %s%s\n", this->file.string(), type, this->error.string()); + fprintf(to, "%s: %s%s\n", this->file.c_str(), type, this->error.c_str()); } } else { - fprintf(to, "%s%s\n", type, this->error.string()); + fprintf(to, "%s%s\n", type, this->error.c_str()); } } diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp index 6cacd32eb91d..8d0268393433 100644 --- a/tools/aapt/StringPool.cpp +++ b/tools/aapt/StringPool.cpp @@ -67,7 +67,7 @@ void printStringPool(const ResStringPool* pool) const size_t NS = pool->size(); for (size_t s=0; s<NS; s++) { auto str = pool->string8ObjectAt(s); - printf("String #" ZD ": %s\n", (ZD_TYPE) s, (str.has_value() ? str->string() : "")); + printf("String #" ZD ": %s\n", (ZD_TYPE) s, (str.has_value() ? str->c_str() : "")); } } @@ -139,7 +139,7 @@ ssize_t StringPool::add(const String16& value, if (eidx < 0) { eidx = mEntries.add(entry(value)); if (eidx < 0) { - fprintf(stderr, "Failure adding string %s\n", String8(value).string()); + fprintf(stderr, "Failure adding string %s\n", String8(value).c_str()); return eidx; } } @@ -148,7 +148,7 @@ ssize_t StringPool::add(const String16& value, entry& ent = mEntries.editItemAt(eidx); if (kIsDebug) { printf("*** adding config type name %s, was %s\n", - configTypeName->string(), ent.configTypeName.string()); + configTypeName->c_str(), ent.configTypeName.c_str()); } if (ent.configTypeName.size() <= 0) { ent.configTypeName = *configTypeName; @@ -166,7 +166,7 @@ ssize_t StringPool::add(const String16& value, if (cmp >= 0) { if (cmp > 0) { if (kIsDebug) { - printf("*** inserting config: %s\n", config->toString().string()); + printf("*** inserting config: %s\n", config->toString().c_str()); } ent.configs.insertAt(*config, addPos); } @@ -175,7 +175,7 @@ ssize_t StringPool::add(const String16& value, } if (addPos >= ent.configs.size()) { if (kIsDebug) { - printf("*** adding config: %s\n", config->toString().string()); + printf("*** adding config: %s\n", config->toString().c_str()); } ent.configs.add(*config); } @@ -195,7 +195,7 @@ ssize_t StringPool::add(const String16& value, if (kIsDebug) { printf("Adding string %s to pool: pos=%zd eidx=%zd vidx=%zd\n", - String8(value).string(), pos, eidx, vidx); + String8(value).c_str(), pos, eidx, vidx); } return pos; @@ -286,13 +286,13 @@ void StringPool::sortByConfig() for (size_t i=0; i<N; i++) { printf("#%d was %d: %s\n", i, newPosToOriginalPos[i], - mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().string()); + mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().c_str()); entries.add(mEntries[mEntryArray[i]]); } for (size_t i=0; i<entries.size(); i++) { printf("Sorted config #%d: %s\n", i, - entries[i].makeConfigsString().string()); + entries[i].makeConfigsString().c_str()); } #endif @@ -363,8 +363,8 @@ void StringPool::sortByConfig() printf("FINAL SORTED STRING CONFIGS:\n"); for (size_t i=0; i<mEntries.size(); i++) { const entry& ent = mEntries[i]; - printf("#" ZD " %s: %s\n", (ZD_TYPE)i, ent.makeConfigsString().string(), - String8(ent.value).string()); + printf("#" ZD " %s: %s\n", (ZD_TYPE)i, ent.makeConfigsString().c_str(), + String8(ent.value).c_str()); } #endif } @@ -415,7 +415,7 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) ssize_t idx = add(span.name, true); if (idx < 0) { fprintf(stderr, "Error adding span for style tag '%s'\n", - String8(span.name).string()); + String8(span.name).c_str()); return idx; } span.span.name.index = (uint32_t)idx; @@ -571,7 +571,7 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) if (kIsDebug) { printf("Writing entry #%zu: \"%s\" ent=%zu off=%zu\n", i, - String8(ent.value).string(), + String8(ent.value).c_str(), mEntryArray[i], ent.offset); } @@ -591,8 +591,8 @@ ssize_t StringPool::offsetForString(const String16& val) const const Vector<size_t>* indices = offsetsForString(val); ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1; if (kIsDebug) { - printf("Offset for string %s: %zd (%s)\n", String8(val).string(), res, - res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8()); + printf("Offset for string %s: %zd (%s)\n", String8(val).c_str(), res, + res >= 0 ? String8(mEntries[mEntryArray[res]].value).c_str() : String8()); } return res; } diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h index e1575410e38b..de1d60cbae42 100644 --- a/tools/aapt/Symbol.h +++ b/tools/aapt/Symbol.h @@ -68,9 +68,9 @@ Symbol::Symbol(const android::String16& p, const android::String16& t, const and android::String8 Symbol::toString() const { return android::String8::format("%s:%s/%s (0x%08x)", - android::String8(package).string(), - android::String8(type).string(), - android::String8(name).string(), + android::String8(package).c_str(), + android::String8(type).c_str(), + android::String8(name).c_str(), (int) id); } diff --git a/tools/aapt/Utils.cpp b/tools/aapt/Utils.cpp new file mode 100644 index 000000000000..36b018e7dd2c --- /dev/null +++ b/tools/aapt/Utils.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Utils.h" + +#include <utils/Compat.h> + +// Separator used by resource paths. This is not platform dependent contrary +// to OS_PATH_SEPARATOR. +#define RES_PATH_SEPARATOR '/' + +using android::String8; + +void convertToResPath([[maybe_unused]] String8& s) { +#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR + size_t len = s.length(); + if (len > 0) { + char* buf = s.lockBuffer(len); + for (char* end = buf + len; buf < end; ++buf) { + if (*buf == OS_PATH_SEPARATOR) *buf = RES_PATH_SEPARATOR; + } + s.unlockBuffer(len); + } +#endif +} diff --git a/tools/aapt/Utils.h b/tools/aapt/Utils.h new file mode 100644 index 000000000000..8eb594138478 --- /dev/null +++ b/tools/aapt/Utils.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// This file contains cruft that used to be in libutils' String8, that's only +// used for aapt. + +#include <utils/String8.h> + +// Converts all separators in this string to /, the default path +// separator. +// If the default OS separator is backslash, this converts all +// backslashes to slashes, in-place. Otherwise it does nothing. +void convertToResPath(android::String8&); diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp index 69392d66e21f..e270a7333295 100644 --- a/tools/aapt/XMLNode.cpp +++ b/tools/aapt/XMLNode.cpp @@ -66,14 +66,14 @@ static const String16 RESOURCES_TOOLS_NAMESPACE("http://schemas.android.com/tool String16 getNamespaceResourcePackage(const String16& appPackage, const String16& namespaceUri, bool* outIsPublic) { - //printf("%s starts with %s?\n", String8(namespaceUri).string(), - // String8(RESOURCES_PREFIX).string()); + //printf("%s starts with %s?\n", String8(namespaceUri).c_str(), + // String8(RESOURCES_PREFIX).c_str()); size_t prefixSize; bool isPublic = true; if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) { if (kIsDebug) { - printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(), - String8(appPackage).string()); + printf("Using default application package: %s -> %s\n", String8(namespaceUri).c_str(), + String8(appPackage).c_str()); } isPublic = true; return appPackage; @@ -88,7 +88,7 @@ String16 getNamespaceResourcePackage(const String16& appPackage, const String16& } //printf("YES!\n"); - //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string()); + //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).c_str()); if (outIsPublic) *outIsPublic = isPublic; return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize); } @@ -97,7 +97,7 @@ status_t hasSubstitutionErrors(const char* fileName, ResXMLTree* inXml, const String16& str16) { - const char16_t* str = str16.string(); + const char16_t* str = str16.c_str(); const char16_t* p = str; const char16_t* end = str + str16.size(); @@ -223,7 +223,7 @@ status_t parseStyledString(Bundle* /* bundle */, String16 text(inXml->getText(&len)); if (firstTime && text.size() > 0) { firstTime = false; - if (text.string()[0] == '@') { + if (text.c_str()[0] == '@') { // If this is a resource reference, don't do the pseudoloc. pseudolocalize = NO_PSEUDOLOCALIZATION; pseudo.setMethod(pseudolocalize); @@ -263,7 +263,7 @@ status_t parseStyledString(Bundle* /* bundle */, { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found unsupported XLIFF tag <%s>\n", - element8.string()); + element8.c_str()); return UNKNOWN_ERROR; } moveon: @@ -272,14 +272,14 @@ moveon: if (outSpans == NULL) { SourcePos(String8(fileName), inXml->getLineNumber()).error( - "Found style tag <%s> where styles are not allowed\n", element8.string()); + "Found style tag <%s> where styles are not allowed\n", element8.c_str()); return UNKNOWN_ERROR; } - if (!ResTable::collectString(outString, curString.string(), + if (!ResTable::collectString(outString, curString.c_str(), curString.size(), false, &errorMsg, true)) { SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", - errorMsg, String8(curString).string()); + errorMsg, String8(curString).c_str()); return UNKNOWN_ERROR; } rawString.append(curString); @@ -295,7 +295,7 @@ moveon: str = inXml->getAttributeStringValue(ai, &len); span.name.append(str, len); } - //printf("Span: %s\n", String8(span.name).string()); + //printf("Span: %s\n", String8(span.name).c_str()); span.span.firstChar = span.span.lastChar = outString->size(); spanStack.push(span); @@ -311,21 +311,21 @@ moveon: xliffDepth--; continue; } - if (!ResTable::collectString(outString, curString.string(), + if (!ResTable::collectString(outString, curString.c_str(), curString.size(), false, &errorMsg, true)) { SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", - errorMsg, String8(curString).string()); + errorMsg, String8(curString).c_str()); return UNKNOWN_ERROR; } rawString.append(curString); curString = String16(); if (spanStack.size() == 0) { - if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) { + if (strcmp16(inXml->getElementName(&len), endTag.c_str()) != 0) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found tag %s where <%s> close is expected\n", - String8(inXml->getElementName(&len)).string(), - String8(endTag).string()); + String8(inXml->getElementName(&len)).c_str(), + String8(endTag).c_str()); return UNKNOWN_ERROR; } break; @@ -334,15 +334,15 @@ moveon: String16 spanTag; ssize_t semi = span.name.findFirst(';'); if (semi >= 0) { - spanTag.setTo(span.name.string(), semi); + spanTag.setTo(span.name.c_str(), semi); } else { spanTag.setTo(span.name); } - if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) { + if (strcmp16(inXml->getElementName(&len), spanTag.c_str()) != 0) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found close tag %s where close tag %s is expected\n", - String8(inXml->getElementName(&len)).string(), - String8(spanTag).string()); + String8(inXml->getElementName(&len)).c_str(), + String8(spanTag).c_str()); return UNKNOWN_ERROR; } bool empty = true; @@ -363,7 +363,7 @@ moveon: if (0 && empty) { fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n", fileName, inXml->getLineNumber(), - String8(spanTag).string(), String8(*outString).string()); + String8(spanTag).c_str(), String8(*outString).c_str()); } } else if (code == ResXMLTree::START_NAMESPACE) { @@ -380,11 +380,11 @@ moveon: if (outSpans != NULL && outSpans->size() > 0) { if (curString.size() > 0) { - if (!ResTable::collectString(outString, curString.string(), + if (!ResTable::collectString(outString, curString.c_str(), curString.size(), false, &errorMsg, true)) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "%s (in %s)\n", - errorMsg, String8(curString).string()); + errorMsg, String8(curString).c_str()); return UNKNOWN_ERROR; } } @@ -450,10 +450,10 @@ void printXMLBlock(ResXMLTree* block) String8 elemNs = build_namespace(namespaces, ns16); const char16_t* com16 = block->getComment(&len); if (com16) { - printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string()); + printf("%s <!-- %s -->\n", prefix.c_str(), String8(com16).c_str()); } - printf("%sE: %s%s (line=%d)\n", prefix.string(), elemNs.string(), - String8(block->getElementName(&len)).string(), + printf("%sE: %s%s (line=%d)\n", prefix.c_str(), elemNs.c_str(), + String8(block->getElementName(&len)).c_str(), block->getLineNumber()); int N = block->getAttributeCount(); depth++; @@ -463,11 +463,11 @@ void printXMLBlock(ResXMLTree* block) ns16 = block->getAttributeNamespace(i, &len); String8 ns = build_namespace(namespaces, ns16); String8 name(block->getAttributeName(i, &len)); - printf("%sA: ", prefix.string()); + printf("%sA: ", prefix.c_str()); if (res) { - printf("%s%s(0x%08x)", ns.string(), name.string(), res); + printf("%s%s(0x%08x)", ns.c_str(), name.c_str(), res); } else { - printf("%s%s", ns.string(), name.string()); + printf("%s%s", ns.c_str(), name.c_str()); } Res_value value; block->getAttributeValue(i, &value); @@ -480,14 +480,14 @@ void printXMLBlock(ResXMLTree* block) } else if (value.dataType == Res_value::TYPE_STRING) { printf("=\"%s\"", ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i, - &len)).string()).string()); + &len)).c_str()).c_str()); } else { printf("=(type 0x%x)0x%x", (int)value.dataType, (int)value.data); } const char16_t* val = block->getAttributeStringValue(i, &len); if (val != NULL) { - printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).string()). - string()); + printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).c_str()). + c_str()); } printf("\n"); } @@ -509,8 +509,8 @@ void printXMLBlock(ResXMLTree* block) } ns.uri = String8(block->getNamespaceUri(&len)); namespaces.push(ns); - printf("%sN: %s=%s\n", prefix.string(), ns.prefix.string(), - ns.uri.string()); + printf("%sN: %s=%s\n", prefix.c_str(), ns.prefix.c_str(), + ns.uri.c_str()); depth++; } else if (code == ResXMLTree::END_NAMESPACE) { if (--depth < 0) { @@ -529,19 +529,19 @@ void printXMLBlock(ResXMLTree* block) if (ns.prefix != pr) { prefix = make_prefix(depth); printf("%s*** BAD END NS PREFIX: found=%s, expected=%s\n", - prefix.string(), pr.string(), ns.prefix.string()); + prefix.c_str(), pr.c_str(), ns.prefix.c_str()); } String8 uri = String8(block->getNamespaceUri(&len)); if (ns.uri != uri) { prefix = make_prefix(depth); printf("%s *** BAD END NS URI: found=%s, expected=%s\n", - prefix.string(), uri.string(), ns.uri.string()); + prefix.c_str(), uri.c_str(), ns.uri.c_str()); } namespaces.pop(); } else if (code == ResXMLTree::TEXT) { size_t len; - printf("%sC: \"%s\"\n", prefix.string(), - ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string()); + printf("%sC: \"%s\"\n", prefix.c_str(), + ResTable::normalizeForOutput(String8(block->getText(&len)).c_str()).c_str()); } } @@ -583,7 +583,7 @@ status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree, sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file) { char buf[16384]; - int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY); + int fd = open(file->getSourceFile().c_str(), O_RDONLY | O_BINARY); if (fd < 0) { SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s", strerror(errno)); @@ -875,9 +875,9 @@ void XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId) } if (kIsDebug) { printf("Elem %s %s=\"%s\": set res id = 0x%08x\n", - String8(getElementName()).string(), - String8(mAttributes.itemAt(attrIdx).name).string(), - String8(mAttributes.itemAt(attrIdx).string).string(), + String8(getElementName()).c_str(), + String8(mAttributes.itemAt(attrIdx).name).c_str(), + String8(mAttributes.itemAt(attrIdx).string).c_str(), resId); } mAttributes.editItemAt(attrIdx).nameResId = resId; @@ -915,7 +915,7 @@ void XMLNode::setEndLineNumber(int32_t line) void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags) { - //printf("Removing whitespace in %s\n", String8(mElementName).string()); + //printf("Removing whitespace in %s\n", String8(mElementName).c_str()); size_t N = mChildren.size(); if (cDataTags) { String8 tag(mElementName); @@ -931,13 +931,13 @@ void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags) sp<XMLNode> node = mChildren.itemAt(i); if (node->getType() == TYPE_CDATA) { // This is a CDATA node... - const char16_t* p = node->mChars.string(); + const char16_t* p = node->mChars.c_str(); while (*p != 0 && *p < 128 && isspace(*p)) { p++; } //printf("Space ends at %d in \"%s\"\n", - // (int)(p-node->mChars.string()), - // String8(node->mChars).string()); + // (int)(p-node->mChars.c_str()), + // String8(node->mChars).c_str()); if (*p == 0) { if (stripAll) { // Remove this node! @@ -949,18 +949,18 @@ void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags) } } else { // Compact leading/trailing whitespace. - const char16_t* e = node->mChars.string()+node->mChars.size()-1; + const char16_t* e = node->mChars.c_str()+node->mChars.size()-1; while (e > p && *e < 128 && isspace(*e)) { e--; } - if (p > node->mChars.string()) { + if (p > node->mChars.c_str()) { p--; } - if (e < (node->mChars.string()+node->mChars.size()-1)) { + if (e < (node->mChars.c_str()+node->mChars.size()-1)) { e++; } - if (p > node->mChars.string() || - e < (node->mChars.string()+node->mChars.size()-1)) { + if (p > node->mChars.c_str() || + e < (node->mChars.c_str()+node->mChars.size()-1)) { String16 tmp(p, e-p+1); node->mChars = tmp; } @@ -986,14 +986,14 @@ status_t XMLNode::parseValues(const sp<AaptAssets>& assets, table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber())); if (!assets->getIncludedResources() .stringToValue(&e.value, &e.string, - e.string.string(), e.string.size(), true, true, + e.string.c_str(), e.string.size(), true, true, e.nameResId, NULL, &defPackage, table, &ac)) { hasErrors = true; } if (kIsDebug) { printf("Attr %s: type=0x%x, str=%s\n", - String8(e.name).string(), e.value.dataType, - String8(e.string).string()); + String8(e.name).c_str(), e.value.dataType, + String8(e.string).c_str()); } } } @@ -1023,30 +1023,30 @@ status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets, String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic)); if (kIsDebug) { printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n", - String8(getElementName()).string(), - String8(e.name).string(), - String8(e.string).string(), - String8(e.ns).string(), + String8(getElementName()).c_str(), + String8(e.name).c_str(), + String8(e.string).c_str(), + String8(e.ns).c_str(), (nsIsPublic) ? "public" : "private", - String8(pkg).string()); + String8(pkg).c_str()); } if (pkg.size() <= 0) continue; uint32_t res = table != NULL ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic) : assets->getIncludedResources(). - identifierForName(e.name.string(), e.name.size(), - attr.string(), attr.size(), - pkg.string(), pkg.size()); + identifierForName(e.name.c_str(), e.name.size(), + attr.c_str(), attr.size(), + pkg.c_str(), pkg.size()); if (res != 0) { if (kIsDebug) { printf("XML attribute name %s: resid=0x%08x\n", - String8(e.name).string(), res); + String8(e.name).c_str(), res); } setAttributeResID(i, res); } else { SourcePos(mFilename, getStartLineNumber()).error( "No resource identifier found for attribute '%s' in package '%s'\n", - String8(e.name).string(), String8(pkg).string()); + String8(e.name).c_str(), String8(pkg).c_str()); hasErrors = true; } } @@ -1137,7 +1137,7 @@ status_t XMLNode::flatten(const sp<AaptFile>& dest, if (kPrintStringMetrics) { fprintf(stderr, "**** total xml size: %zu / %zu%% strings (in %s)\n", dest->getSize(), (stringPool->getSize()*100)/dest->getSize(), - dest->getPath().string()); + dest->getPath().c_str()); } return NO_ERROR; @@ -1155,8 +1155,8 @@ void XMLNode::print(int indent) if (elemNs.size() > 0) { elemNs.append(":"); } - printf("%s E: %s%s", prefix.string(), - elemNs.string(), String8(getElementName()).string()); + printf("%s E: %s%s", prefix.c_str(), + elemNs.c_str(), String8(getElementName()).c_str()); int N = mAttributes.size(); for (i=0; i<N; i++) { ssize_t idx = mAttributeOrder.valueAt(i); @@ -1171,21 +1171,21 @@ void XMLNode::print(int indent) attrNs.append(":"); } if (attr.nameResId) { - printf("%s%s(0x%08x)", attrNs.string(), - String8(attr.name).string(), attr.nameResId); + printf("%s%s(0x%08x)", attrNs.c_str(), + String8(attr.name).c_str(), attr.nameResId); } else { - printf("%s%s", attrNs.string(), String8(attr.name).string()); + printf("%s%s", attrNs.c_str(), String8(attr.name).c_str()); } - printf("=%s", String8(attr.string).string()); + printf("=%s", String8(attr.string).c_str()); } printf("\n"); } else if (getType() == TYPE_NAMESPACE) { - printf("%s N: %s=%s\n", prefix.string(), + printf("%s N: %s=%s\n", prefix.c_str(), getNamespacePrefix().size() > 0 - ? String8(getNamespacePrefix()).string() : "<DEF>", - String8(getNamespaceUri()).string()); + ? String8(getNamespacePrefix()).c_str() : "<DEF>", + String8(getNamespaceUri()).c_str()); } else { - printf("%s C: \"%s\"\n", prefix.string(), String8(getCData()).string()); + printf("%s C: \"%s\"\n", prefix.c_str(), String8(getCData()).c_str()); } int N = mChildren.size(); for (i=0; i<N; i++) { @@ -1258,7 +1258,7 @@ void XMLCALL XMLNode::characterData(void *userData, const XML_Char *s, int len) { if (kIsDebugParse) { - printf("CDATA: \"%s\"\n", String8(s, len).string()); + printf("CDATA: \"%s\"\n", String8(s, len).c_str()); } ParseState* st = (ParseState*)userData; sp<XMLNode> node = NULL; @@ -1423,7 +1423,7 @@ status_t XMLNode::collect_attr_strings(StringPool* outPool, idx = outPool->add(attr.name); if (kIsDebug) { printf("Adding attr %s (resid 0x%08x) to pool: idx=%zd\n", - String8(attr.name).string(), id, idx); + String8(attr.name).c_str(), id, idx); } if (id != 0) { while ((ssize_t)outResIds->size() <= idx) { @@ -1434,7 +1434,7 @@ status_t XMLNode::collect_attr_strings(StringPool* outPool, } attr.namePoolIdx = idx; if (kIsDebug) { - printf("String %s offset=0x%08zd\n", String8(attr.name).string(), idx); + printf("String %s offset=0x%08zd\n", String8(attr.name).c_str(), idx); } } } @@ -1488,7 +1488,7 @@ status_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& de node.comment.index = htodl( mComment.size() > 0 ? strings.offsetForString(mComment) : -1); //if (mComment.size() > 0) { - // printf("Flattening comment: %s\n", String8(mComment).string()); + // printf("Flattening comment: %s\n", String8(mComment).c_str()); //} } else { node.comment.index = htodl((uint32_t)-1); diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp index 4e8dcb1bc6ee..fc2ed98949dd 100644 --- a/tools/aapt/pseudolocalize.cpp +++ b/tools/aapt/pseudolocalize.cpp @@ -42,7 +42,7 @@ String16 Pseudolocalizer::text(const String16& text) { size_t depth = mLastDepth; size_t lastpos, pos; const size_t length= text.size(); - const char16_t* str = text.string(); + const char16_t* str = text.c_str(); bool escaped = false; for (lastpos = pos = 0; pos < length; pos++) { char16_t c = str[pos]; @@ -181,7 +181,7 @@ static bool is_possible_normal_placeholder_end(const char16_t c) { static String16 pseudo_generate_expansion(const unsigned int length) { String16 result = k_expansion_string; - const char16_t* s = result.string(); + const char16_t* s = result.c_str(); if (result.size() < length) { result += String16(" "); result += pseudo_generate_expansion(length - result.size()); @@ -237,7 +237,7 @@ String16 PseudoMethodAccent::end() { */ String16 PseudoMethodAccent::text(const String16& source) { - const char16_t* s = source.string(); + const char16_t* s = source.c_str(); String16 result; const size_t I = source.size(); bool lastspace = true; @@ -357,7 +357,7 @@ String16 PseudoMethodAccent::placeholder(const String16& source) { String16 PseudoMethodBidi::text(const String16& source) { - const char16_t* s = source.string(); + const char16_t* s = source.c_str(); String16 result; bool lastspace = true; bool space = true; diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index 0d6dc3522d24..7323b0f4c14f 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -47,6 +47,7 @@ cc_defaults { "-Wno-missing-field-initializers", "-fno-exceptions", "-fno-rtti", + "-Wno-deprecated-declarations", ], target: { windows: { diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index df878899fa28..6a17ef85a755 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -265,6 +265,16 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& ValueHeadlinePrinter headline_printer(package.name, printer); ValueBodyPrinter body_printer(package.name, printer); + auto& dynamicRefTable = table.GetReferencedPackages(); + if (!dynamicRefTable.empty()) { + printer->Println(StringPrintf("DynamicRefTable entryCount=%d", int(dynamicRefTable.size()))); + printer->Indent(); + for (auto&& [id, name] : dynamicRefTable) { + printer->Println(StringPrintf("0x%02x -> %s", id, name.c_str())); + } + printer->Undent(); + } + printer->Print("Package name="); printer->Print(package.name); if (package.id) { @@ -447,7 +457,7 @@ void Debug::DumpResStringPool(const android::ResStringPool* pool, text::Printer* const size_t NS = pool->size(); for (size_t s=0; s<NS; s++) { auto str = pool->string8ObjectAt(s); - printer->Print(StringPrintf("String #%zd : %s\n", s, str.has_value() ? str->string() : "")); + printer->Print(StringPrintf("String #%zd : %s\n", s, str.has_value() ? str->c_str() : "")); } } diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h index 4cd7eae0a5e2..27c354a7b08e 100644 --- a/tools/aapt2/LoadedApk.h +++ b/tools/aapt2/LoadedApk.h @@ -40,10 +40,8 @@ enum ApkFormat { }; // Info about an APK loaded in memory. -class LoadedApk { +class LoadedApk final { public: - virtual ~LoadedApk() = default; - // Loads both binary and proto APKs from disk. static std::unique_ptr<LoadedApk> LoadApkFromPath(android::StringPiece path, android::IDiagnostics* diag); @@ -96,8 +94,8 @@ class LoadedApk { * Writes the APK on disk at the given path, while also removing the resource * files that are not referenced in the resource table. */ - virtual bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options, - IArchiveWriter* writer); + bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options, + IArchiveWriter* writer); /** * Writes the APK on disk at the given path, while also removing the resource files that are not @@ -108,9 +106,9 @@ class LoadedApk { * original manifest will be written. The manifest is only required if the contents of the new APK * have been modified in a way that require the AndroidManifest.xml to also be modified. */ - virtual bool WriteToArchive(IAaptContext* context, ResourceTable* split_table, - const TableFlattenerOptions& options, FilterChain* filters, - IArchiveWriter* writer, xml::XmlResource* manifest = nullptr); + bool WriteToArchive(IAaptContext* context, ResourceTable* split_table, + const TableFlattenerOptions& options, FilterChain* filters, + IArchiveWriter* writer, xml::XmlResource* manifest = nullptr); /** Loads the file as an xml document. */ std::unique_ptr<xml::XmlResource> LoadXml(const std::string& file_path, diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index fa9a98f136cb..6af39b739e9b 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -800,7 +800,7 @@ std::unique_ptr<Item> ResourceParser::ParseXml(const FlattenedXmlSubTree& xmlsub // Process the raw value. std::unique_ptr<Item> processed_item = ResourceUtils::TryParseItemForAttribute( - xmlsub_tree.raw_value, type_mask, on_create_reference); + &diag, xmlsub_tree.raw_value, type_mask, on_create_reference); if (processed_item) { // Fix up the reference. if (auto ref = ValueCast<Reference>(processed_item.get())) { diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h index bb286a8abdaa..61e399c7ab68 100644 --- a/tools/aapt2/ResourceTable.h +++ b/tools/aapt2/ResourceTable.h @@ -307,6 +307,11 @@ class ResourceTable { // order. ResourceTableView GetPartitionedView(const ResourceTableViewOptions& options = {}) const; + using ReferencedPackages = std::map<uint8_t, std::string>; + const ReferencedPackages& GetReferencedPackages() const { + return included_packages_; + } + struct SearchResult { ResourceTablePackage* package; ResourceTableType* type; @@ -342,7 +347,7 @@ class ResourceTable { // Set of dynamic packages that this table may reference. Their package names get encoded // into the resources.arsc along with their compile-time assigned IDs. - std::map<size_t, std::string> included_packages_; + ReferencedPackages included_packages_; private: DISALLOW_COPY_AND_ASSIGN(ResourceTable); diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp index 5a118a902963..d358df98ada6 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -619,7 +619,7 @@ uint32_t AndroidTypeToAttributeTypeMask(uint16_t type) { } std::unique_ptr<Item> TryParseItemForAttribute( - StringPiece value, uint32_t type_mask, + android::IDiagnostics* diag, StringPiece value, uint32_t type_mask, const std::function<bool(const ResourceName&)>& on_create_reference) { using android::ResTable_map; @@ -670,8 +670,32 @@ std::unique_ptr<Item> TryParseItemForAttribute( // Try parsing this as a float. auto floating_point = TryParseFloat(value); if (floating_point) { + // Only check if the parsed result lost precision when the parsed item is + // android::Res_value::TYPE_FLOAT and there is other possible types saved in type_mask, like + // ResTable_map::TYPE_INTEGER. if (type_mask & AndroidTypeToAttributeTypeMask(floating_point->value.dataType)) { - return std::move(floating_point); + const bool mayOnlyBeFloat = (type_mask & ~float_mask) == 0; + const bool parsedAsFloat = floating_point->value.dataType == android::Res_value::TYPE_FLOAT; + if (!mayOnlyBeFloat && parsedAsFloat) { + float f = reinterpret_cast<float&>(floating_point->value.data); + std::u16string str16 = android::util::Utf8ToUtf16(util::TrimWhitespace(value)); + double d; + if (android::ResTable::stringToDouble(str16.data(), str16.size(), d)) { + // Parse as a float only if the difference between float and double parsed from the + // same string is smaller than 1, otherwise return as raw string. + if (fabs(f - d) < 1) { + return std::move(floating_point); + } else { + if (diag->IsVerbose()) { + diag->Note(android::DiagMessage() + << "precision lost greater than 1 while parsing float " << value + << ", return a raw string"); + } + } + } + } else { + return std::move(floating_point); + } } } } @@ -683,12 +707,12 @@ std::unique_ptr<Item> TryParseItemForAttribute( * allows. */ std::unique_ptr<Item> TryParseItemForAttribute( - StringPiece str, const Attribute* attr, + android::IDiagnostics* diag, StringPiece str, const Attribute* attr, const std::function<bool(const ResourceName&)>& on_create_reference) { using android::ResTable_map; const uint32_t type_mask = attr->type_mask; - auto value = TryParseItemForAttribute(str, type_mask, on_create_reference); + auto value = TryParseItemForAttribute(diag, str, type_mask, on_create_reference); if (value) { return value; } diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h index f30f4acfec7a..50fc87900162 100644 --- a/tools/aapt2/ResourceUtils.h +++ b/tools/aapt2/ResourceUtils.h @@ -200,11 +200,11 @@ std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* enum_attr, * reference to an ID that must be created (@+id/foo). */ std::unique_ptr<Item> TryParseItemForAttribute( - android::StringPiece value, const Attribute* attr, + android::IDiagnostics* diag, android::StringPiece value, const Attribute* attr, const std::function<bool(const ResourceName&)>& on_create_reference = {}); std::unique_ptr<Item> TryParseItemForAttribute( - android::StringPiece value, uint32_t type_mask, + android::IDiagnostics* diag, android::StringPiece value, uint32_t type_mask, const std::function<bool(const ResourceName&)>& on_create_reference = {}); uint32_t AndroidTypeToAttributeTypeMask(uint16_t type); diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp index 568871a4d66e..4cba04de72ee 100644 --- a/tools/aapt2/ResourceUtils_test.cpp +++ b/tools/aapt2/ResourceUtils_test.cpp @@ -217,17 +217,46 @@ TEST(ResourceUtilsTest, EmptyIsBinaryPrimitive) { } TEST(ResourceUtilsTest, ItemsWithWhitespaceAreParsedCorrectly) { - EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" 12\n ", ResTable_map::TYPE_INTEGER), + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), " 12\n ", + ResTable_map::TYPE_INTEGER), Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_INT_DEC, 12u)))); - EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" true\n ", ResTable_map::TYPE_BOOLEAN), + EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), " true\n ", + ResTable_map::TYPE_BOOLEAN), Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_INT_BOOLEAN, 0xffffffffu)))); const float expected_float = 12.0f; const uint32_t expected_float_flattened = *(uint32_t*)&expected_float; - EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" 12.0\n ", ResTable_map::TYPE_FLOAT), + EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), " 12.0\n ", + ResTable_map::TYPE_FLOAT), Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened)))); } +TEST(ResourceUtilsTest, FloatAndBigIntegerParsedCorrectly) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + const float expected_float = 0.125f; + const uint32_t expected_float_flattened = *(uint32_t*)&expected_float; + EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "0.125", + ResTable_map::TYPE_FLOAT), + Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened)))); + + const float special_float = 1.0f; + const uint32_t special_float_flattened = *(uint32_t*)&special_float; + EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "1.0", + ResTable_map::TYPE_FLOAT), + Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, special_float_flattened)))); + + EXPECT_EQ(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "1099511627776", + ResTable_map::TYPE_INTEGER), + std::unique_ptr<Item>(nullptr)); + + const float big_float = 1099511627776.0f; + const uint32_t big_flattened = *(uint32_t*)&big_float; + EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "1099511627776", + ResTable_map::TYPE_FLOAT), + Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, big_flattened)))); +} + TEST(ResourceUtilsTest, ParseSdkVersionWithCodename) { EXPECT_THAT(ResourceUtils::ParseSdkVersion("Q"), Eq(std::optional<int>(10000))); EXPECT_THAT(ResourceUtils::ParseSdkVersion("Q.fingerprint"), Eq(std::optional<int>(10000))); diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index a5754e0d168f..166b01bd9154 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -439,6 +439,21 @@ static std::string ComplexToString(uint32_t complex_value, bool fraction) { return str; } +// This function is designed to using different specifier to print different floats, +// which can print more accurate format rather than using %g only. +const char* BinaryPrimitive::DecideFormat(float f) { + // if the float is either too big or too tiny, print it in scientific notation. + // eg: "10995116277760000000000" to 1.099512e+22, "0.00000000001" to 1.000000e-11 + if (fabs(f) > std::numeric_limits<int64_t>::max() || fabs(f) < 1e-10) { + return "%e"; + // Else if the number is an integer exactly, print it without trailing zeros. + // eg: "1099511627776" to 1099511627776 + } else if (int64_t(f) == f) { + return "%.0f"; + } + return "%g"; +} + void BinaryPrimitive::PrettyPrint(Printer* printer) const { using ::android::Res_value; switch (value.dataType) { @@ -470,7 +485,9 @@ void BinaryPrimitive::PrettyPrint(Printer* printer) const { break; case Res_value::TYPE_FLOAT: - printer->Print(StringPrintf("%g", *reinterpret_cast<const float*>(&value.data))); + float f; + f = *reinterpret_cast<const float*>(&value.data); + printer->Print(StringPrintf(DecideFormat(f), f)); break; case Res_value::TYPE_DIMENSION: diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h index 6f9dccbd3bcc..5192c2be1f98 100644 --- a/tools/aapt2/ResourceValues.h +++ b/tools/aapt2/ResourceValues.h @@ -284,6 +284,7 @@ struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<Bina bool Equals(const Value* value) const override; bool Flatten(android::Res_value* out_value) const override; void Print(std::ostream* out) const override; + static const char* DecideFormat(float f); void PrettyPrint(text::Printer* printer) const override; }; diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp index a7c5479b56fd..83f2eb31aa57 100644 --- a/tools/aapt2/SdkConstants.cpp +++ b/tools/aapt2/SdkConstants.cpp @@ -16,20 +16,24 @@ #include "SdkConstants.h" +#include <stdint.h> + #include <algorithm> #include <string> -#include <unordered_set> -#include <vector> +#include <string_view> using android::StringPiece; +using namespace std::literals; namespace aapt { -static ApiVersion sDevelopmentSdkLevel = 10000; -static const auto sDevelopmentSdkCodeNames = - std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu", "UpsideDownCake"}); +static constexpr ApiVersion sDevelopmentSdkLevel = 10000; +static constexpr StringPiece sDevelopmentSdkCodeNames[] = { + "Q"sv, "R"sv, "S"sv, "Sv2"sv, "Tiramisu"sv, "UpsideDownCake"sv, "VanillaIceCream"sv}; + +static constexpr auto sPrivacySandboxSuffix = "PrivacySandbox"sv; -static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = { +static constexpr std::pair<uint16_t, ApiVersion> sAttrIdMap[] = { {0x021c, 1}, {0x021d, 2}, {0x0269, SDK_CUPCAKE}, @@ -62,25 +66,37 @@ static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = { {0x064c, SDK_S_V2}, }; -static bool less_entry_id(const std::pair<uint16_t, ApiVersion>& p, uint16_t entryId) { - return p.first < entryId; -} +static_assert(std::is_sorted(std::begin(sAttrIdMap), std::end(sAttrIdMap), + [](auto&& l, auto&& r) { return l.first < r.first; })); ApiVersion FindAttributeSdkLevel(const ResourceId& id) { if (id.package_id() != 0x01 || id.type_id() != 0x01) { return 0; } - auto iter = std::lower_bound(sAttrIdMap.begin(), sAttrIdMap.end(), id.entry_id(), less_entry_id); - if (iter == sAttrIdMap.end()) { + const auto it = + std::lower_bound(std::begin(sAttrIdMap), std::end(sAttrIdMap), id.entry_id(), + [](const auto& pair, uint16_t entryId) { return pair.first < entryId; }); + if (it == std::end(sAttrIdMap)) { return SDK_LOLLIPOP_MR1; } - return iter->second; + return it->second; } std::optional<ApiVersion> GetDevelopmentSdkCodeNameVersion(StringPiece code_name) { - return (sDevelopmentSdkCodeNames.find(code_name) == sDevelopmentSdkCodeNames.end()) - ? std::optional<ApiVersion>() - : sDevelopmentSdkLevel; + const auto it = + std::find_if(std::begin(sDevelopmentSdkCodeNames), std::end(sDevelopmentSdkCodeNames), + [code_name](const auto& item) { return code_name.starts_with(item); }); + if (it == std::end(sDevelopmentSdkCodeNames)) { + return {}; + } + if (code_name.size() == it->size()) { + return sDevelopmentSdkLevel; + } + if (code_name.size() == it->size() + sPrivacySandboxSuffix.size() && + code_name.ends_with(sPrivacySandboxSuffix)) { + return sDevelopmentSdkLevel; + } + return {}; } } // namespace aapt diff --git a/tools/aapt2/SdkConstants_test.cpp b/tools/aapt2/SdkConstants_test.cpp index 61f4d71b7fb2..0f645ffc1e8b 100644 --- a/tools/aapt2/SdkConstants_test.cpp +++ b/tools/aapt2/SdkConstants_test.cpp @@ -28,4 +28,24 @@ TEST(SdkConstantsTest, NonFrameworkAttributeIsSdk0) { EXPECT_EQ(0, FindAttributeSdkLevel(ResourceId(0x7f010345))); } +TEST(SdkConstantsTest, GetDevelopmentSdkCodeNameVersionValid) { + EXPECT_EQ(std::optional<ApiVersion>(10000), GetDevelopmentSdkCodeNameVersion("Q")); + EXPECT_EQ(std::optional<ApiVersion>(10000), GetDevelopmentSdkCodeNameVersion("VanillaIceCream")); +} + +TEST(SdkConstantsTest, GetDevelopmentSdkCodeNameVersionPrivacySandbox) { + EXPECT_EQ(std::optional<ApiVersion>(10000), GetDevelopmentSdkCodeNameVersion("QPrivacySandbox")); + EXPECT_EQ(std::optional<ApiVersion>(10000), + GetDevelopmentSdkCodeNameVersion("VanillaIceCreamPrivacySandbox")); +} + +TEST(SdkConstantsTest, GetDevelopmentSdkCodeNameVersionInvalid) { + EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("A")); + EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("Sv3")); + EXPECT_EQ(std::optional<ApiVersion>(), + GetDevelopmentSdkCodeNameVersion("VanillaIceCream_PrivacySandbox")); + EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("PrivacySandbox")); + EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("QQQQQQQQQQQQQQQ")); +} + } // namespace aapt diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp index 03f9715fb265..b5c290ec8dad 100644 --- a/tools/aapt2/cmd/Compile.cpp +++ b/tools/aapt2/cmd/Compile.cpp @@ -186,7 +186,20 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options, // These are created as weak symbols, and are only generated from default // configuration // strings and plurals. - PseudolocaleGenerator pseudolocale_generator; + std::string grammatical_gender_values; + std::string grammatical_gender_ratio; + if (options.pseudo_localize_gender_values) { + grammatical_gender_values = options.pseudo_localize_gender_values.value(); + } else { + grammatical_gender_values = "f,m,n"; + } + if (options.pseudo_localize_gender_ratio) { + grammatical_gender_ratio = options.pseudo_localize_gender_ratio.value(); + } else { + grammatical_gender_ratio = "1.0"; + } + PseudolocaleGenerator pseudolocale_generator(grammatical_gender_values, + grammatical_gender_ratio); if (!pseudolocale_generator.Consume(context, &table)) { return false; } @@ -597,6 +610,7 @@ class CompileContext : public IAaptContext { void SetVerbose(bool val) { verbose_ = val; + diagnostics_->SetVerbose(val); } bool IsVerbose() override { diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h index 14a730a1b1a0..22890fc53d5c 100644 --- a/tools/aapt2/cmd/Compile.h +++ b/tools/aapt2/cmd/Compile.h @@ -35,6 +35,8 @@ struct CompileOptions { std::optional<std::string> res_dir; std::optional<std::string> res_zip; std::optional<std::string> generate_text_symbols_path; + std::optional<std::string> pseudo_localize_gender_values; + std::optional<std::string> pseudo_localize_gender_ratio; std::optional<Visibility::Level> visibility; bool pseudolocalize = false; bool no_png_crunch = false; @@ -76,6 +78,15 @@ class CompileCommand : public Command { AddOptionalFlag("--source-path", "Sets the compiled resource file source file path to the given string.", &options_.source_path); + AddOptionalFlag("--pseudo-localize-gender-values", + "Sets the gender values to pick up for generating grammatical gender strings, " + "gender values should be f, m, or n, which are shortcuts for feminine, " + "masculine and neuter, and split with comma.", + &options_.pseudo_localize_gender_values); + AddOptionalFlag("--pseudo-localize-gender-ratio", + "Sets the ratio of resources to generate grammatical gender strings for. The " + "ratio has to be a float number between 0 and 1.", + &options_.pseudo_localize_gender_ratio); } int Action(const std::vector<std::string>& args) override; diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp index 3464a7662c60..8880089d0e20 100644 --- a/tools/aapt2/cmd/Compile_test.cpp +++ b/tools/aapt2/cmd/Compile_test.cpp @@ -236,9 +236,24 @@ TEST_F(CompilerTest, DoNotTranslateTest) { // The first string (000) is translatable, the second is not // ar-XB uses "\u200F\u202E...\u202C\u200F" std::vector<std::string> expected_translatable = { - "000", "111", // default locale - "[000 one]", // en-XA - "\xE2\x80\x8F\xE2\x80\xAE" "000" "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB + "(F)[000 one]", // en-XA-feminine + "(F)\xE2\x80\x8F\xE2\x80\xAE" + "000" + "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB-feminine + "(M)[000 one]", // en-XA-masculine + "(M)\xE2\x80\x8F\xE2\x80\xAE" + "000" + "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB-masculine + "(N)[000 one]", // en-XA-neuter + "(N)\xE2\x80\x8F\xE2\x80\xAE" + "000" + "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB-neuter + "000", // default locale + "111", // default locale + "[000 one]", // en-XA + "\xE2\x80\x8F\xE2\x80\xAE" + "000" + "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB }; AssertTranslations(this, "foo", expected_translatable); AssertTranslations(this, "foo_donottranslate", expected_translatable); diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp index 7381a85f4339..387dcfe2ddf3 100644 --- a/tools/aapt2/cmd/Convert.cpp +++ b/tools/aapt2/cmd/Convert.cpp @@ -425,6 +425,7 @@ int ConvertCommand::Action(const std::vector<std::string>& args) { if (force_sparse_encoding_) { table_flattener_options_.sparse_entries = SparseEntriesMode::Forced; } + table_flattener_options_.use_compact_entries = enable_compact_entries_; if (resources_config_path_) { if (!ExtractResourceConfig(*resources_config_path_, &context, table_flattener_options_)) { return 1; diff --git a/tools/aapt2/cmd/Convert.h b/tools/aapt2/cmd/Convert.h index 15fe11fd91cc..9452e588953e 100644 --- a/tools/aapt2/cmd/Convert.h +++ b/tools/aapt2/cmd/Convert.h @@ -46,6 +46,10 @@ class ConvertCommand : public Command { "This decreases APK size at the cost of resource retrieval performance.\n" "Applies sparse encoding to all resources regardless of minSdk.", &force_sparse_encoding_); + AddOptionalSwitch( + "--enable-compact-entries", + "This decreases APK size by using compact resource entries for simple data types.", + &enable_compact_entries_); AddOptionalSwitch("--keep-raw-values", android::base::StringPrintf("Preserve raw attribute values in xml files when using the" " '%s' output format", kOutputFormatBinary), @@ -85,6 +89,7 @@ class ConvertCommand : public Command { bool verbose_ = false; bool enable_sparse_encoding_ = false; bool force_sparse_encoding_ = false; + bool enable_compact_entries_ = false; std::optional<std::string> resources_config_path_; }; diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp index 71b08022f688..864af06f187e 100644 --- a/tools/aapt2/cmd/Dump.cpp +++ b/tools/aapt2/cmd/Dump.cpp @@ -112,6 +112,7 @@ class DumpContext : public IAaptContext { void SetVerbose(bool val) { verbose_ = val; + diagnostics_.SetVerbose(val); } int GetMinSdkVersion() override { diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index 97404fc69af2..eb4e38c5f35f 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -148,6 +148,7 @@ class LinkContext : public IAaptContext { void SetVerbose(bool val) { verbose_ = val; + diagnostics_->SetVerbose(val); } int GetMinSdkVersion() override { diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp index 28fcc1a4800e..7096f5cc54e3 100644 --- a/tools/aapt2/cmd/Link_test.cpp +++ b/tools/aapt2/cmd/Link_test.cpp @@ -441,8 +441,8 @@ static void BuildNonFinalizedSDK(const std::string& apk_path, const std::string& R"(<resources> <public type="attr" name="finalized_res" id="0x01010001"/> - <!-- S staged attributes (support staged resources in the same type id) --> - <staging-public-group type="attr" first-id="0x01010050"> + <!-- S staged attributes (Not support staged resources in the same type id) --> + <staging-public-group type="attr" first-id="0x01fc0050"> <public name="staged_s_res" /> </staging-public-group> @@ -480,8 +480,8 @@ static void BuildFinalizedSDK(const std::string& apk_path, const std::string& ja <public type="attr" name="staged_s2_res" id="0x01010003"/> <public type="string" name="staged_s_string" id="0x01020000"/> - <!-- S staged attributes (support staged resources in the same type id) --> - <staging-public-group-final type="attr" first-id="0x01010050"> + <!-- S staged attributes (Not support staged resources in the same type id) --> + <staging-public-group-final type="attr" first-id="0x01fc0050"> <public name="staged_s_res" /> </staging-public-group-final> @@ -551,7 +551,7 @@ TEST_F(LinkTest, StagedAndroidApi) { EXPECT_THAT(android_r_contents, HasSubstr("public static final int finalized_res=0x01010001;")); EXPECT_THAT( android_r_contents, - HasSubstr("public static final int staged_s_res; static { staged_s_res=0x01010050; }")); + HasSubstr("public static final int staged_s_res; static { staged_s_res=0x01fc0050; }")); EXPECT_THAT( android_r_contents, HasSubstr("public static final int staged_s_string; static { staged_s_string=0x01fd0080; }")); @@ -575,7 +575,7 @@ TEST_F(LinkTest, StagedAndroidApi) { android::AssetManager2 am; auto android_asset = android::ApkAssets::Load(android_apk); ASSERT_THAT(android_asset, NotNull()); - ASSERT_TRUE(am.SetApkAssets({android_asset.get()})); + ASSERT_TRUE(am.SetApkAssets({android_asset})); auto result = am.GetResourceId("android:attr/finalized_res"); ASSERT_TRUE(result.has_value()); @@ -583,7 +583,7 @@ TEST_F(LinkTest, StagedAndroidApi) { result = am.GetResourceId("android:attr/staged_s_res"); ASSERT_TRUE(result.has_value()); - EXPECT_THAT(*result, Eq(0x01010050)); + EXPECT_THAT(*result, Eq(0x01fc0050)); result = am.GetResourceId("android:string/staged_s_string"); ASSERT_TRUE(result.has_value()); @@ -631,7 +631,7 @@ TEST_F(LinkTest, FinalizedAndroidApi) { auto app_against_non_final = android::ApkAssets::Load(app_apk); ASSERT_THAT(android_asset, NotNull()); ASSERT_THAT(app_against_non_final, NotNull()); - ASSERT_TRUE(am.SetApkAssets({android_asset.get(), app_against_non_final.get()})); + ASSERT_TRUE(am.SetApkAssets({android_asset, app_against_non_final})); auto result = am.GetResourceId("android:attr/finalized_res"); ASSERT_TRUE(result.has_value()); @@ -667,7 +667,7 @@ TEST_F(LinkTest, FinalizedAndroidApi) { auto app_against_final = android::ApkAssets::Load(app_apk_respin); ASSERT_THAT(app_against_final, NotNull()); - ASSERT_TRUE(am.SetApkAssets({android_asset.get(), app_against_final.get()})); + ASSERT_TRUE(am.SetApkAssets({android_asset, app_against_final})); { auto style = am.GetBag(0x7f020000); diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp index dbe79701bf5c..f045dad6d11a 100644 --- a/tools/aapt2/cmd/Optimize.cpp +++ b/tools/aapt2/cmd/Optimize.cpp @@ -101,6 +101,7 @@ class OptimizeContext : public IAaptContext { void SetVerbose(bool val) { verbose_ = val; + diagnostics_.SetVerbose(val); } void SetMinSdkVersion(int sdk_version) { diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp index 1671e1e1a6a1..a92f24b82547 100644 --- a/tools/aapt2/cmd/Util.cpp +++ b/tools/aapt2/cmd/Util.cpp @@ -215,7 +215,7 @@ std::unique_ptr<xml::XmlResource> GenerateSplitManifest(const AppInfo& app_info, } std::vector<std::string> sanitized_config_names; for (const auto &config : constraints.configs) { - sanitized_config_names.push_back(MakePackageSafeName(config.toString().string())); + sanitized_config_names.push_back(MakePackageSafeName(config.toString().c_str())); } split_name << "config." << util::Joiner(sanitized_config_names, "_"); diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp index b3f98a9d3e30..5421abde3689 100644 --- a/tools/aapt2/compile/IdAssigner.cpp +++ b/tools/aapt2/compile/IdAssigner.cpp @@ -37,6 +37,7 @@ using Result = expected<T, std::string>; template <typename Id, typename Key> struct NextIdFinder { + std::map<Id, Key> pre_assigned_ids_; explicit NextIdFinder(Id start_id = 0u) : next_id_(start_id){}; // Attempts to reserve an identifier for the specified key. @@ -55,7 +56,6 @@ struct NextIdFinder { Id next_id_; bool next_id_called_ = false; bool exhausted_ = false; - std::map<Id, Key> pre_assigned_ids_; typename std::map<Id, Key>::iterator next_preassigned_id_; }; @@ -158,7 +158,7 @@ bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) { } if (assigned_id_map_) { - // Reserve all the IDs mentioned in the stable ID map. That way we won't assig IDs that were + // Reserve all the IDs mentioned in the stable ID map. That way we won't assign IDs that were // listed in the map if they don't exist in the table. for (const auto& stable_id_entry : *assigned_id_map_) { const ResourceName& pre_assigned_name = stable_id_entry.first; @@ -191,6 +191,11 @@ bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) { } namespace { +static const std::string_view staged_type_overlap_error = + "Staged public resource type IDs have conflict with non staged public resources type " + "IDs, please restart staged resource type ID assignment at 0xff in public-staging.xml " + "and also delete all the overlapping groups in public-final.xml"; + template <typename Id, typename Key> Result<Id> NextIdFinder<Id, Key>::ReserveId(Key key, Id id) { CHECK(!next_id_called_) << "ReserveId cannot be called after NextId"; @@ -282,8 +287,20 @@ bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id, // another type. auto assign_result = type_id_finder_.ReserveId(key, id.type_id()); if (!assign_result.has_value()) { - diag->Error(android::DiagMessage() << "can't assign ID " << id << " to resource " << name - << " because type " << assign_result.error()); + auto pre_assigned_type = type_id_finder_.pre_assigned_ids_[id.type_id()].type; + bool pre_assigned_type_staged = + non_staged_type_ids_.find(pre_assigned_type) == non_staged_type_ids_.end(); + auto hex_type_id = fmt::format("{:#04x}", (int)id.type_id()); + bool current_type_staged = visibility.staged_api; + diag->Error(android::DiagMessage() + << "can't assign type ID " << hex_type_id << " to " + << (current_type_staged ? "staged type " : "non staged type ") << name.type.type + << " because this type ID have been assigned to " + << (pre_assigned_type_staged ? "staged type " : "non staged type ") + << pre_assigned_type); + if (pre_assigned_type_staged || current_type_staged) { + diag->Error(android::DiagMessage() << staged_type_overlap_error); + } return false; } type = types_.emplace(key, TypeGroup(package_id_, id.type_id())).first; @@ -298,6 +315,20 @@ bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id, << " because type already has ID " << std::hex << (int)id.type_id()); return false; } + } else { + // Ensure that staged public resources cannot have the same type name and type id with + // non staged public resources. + auto non_staged_type = non_staged_type_ids_.find(name.type.type); + if (non_staged_type != non_staged_type_ids_.end() && non_staged_type->second == id.type_id()) { + diag->Error( + android::DiagMessage() + << "can`t assign type ID " << fmt::format("{:#04x}", (int)id.type_id()) + << " to staged type " << name.type.type << " because type ID " + << fmt::format("{:#04x}", (int)id.type_id()) + << " already has been assigned to a non staged resource type with the same type name"); + diag->Error(android::DiagMessage() << staged_type_overlap_error); + return false; + } } auto assign_result = type->second.ReserveId(name, id); diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp index 8911dad39470..ce45b7c1df04 100644 --- a/tools/aapt2/compile/IdAssigner_test.cpp +++ b/tools/aapt2/compile/IdAssigner_test.cpp @@ -117,14 +117,28 @@ TEST_F(IdAssignerTests, FailWhenTypeHasTwoNonStagedIds) { } TEST_F(IdAssignerTests, FailWhenTypeHasTwoNonStagedIdsRegardlessOfStagedId) { - auto table = test::ResourceTableBuilder() - .AddSimple("android:attr/foo", ResourceId(0x01050000)) - .AddSimple("android:attr/bar", ResourceId(0x01ff0006)) - .Add(NewResourceBuilder("android:attr/staged_baz") - .SetId(0x01ff0000) - .SetVisibility({.staged_api = true}) - .Build()) - .Build(); + auto table = + test::ResourceTableBuilder() + .AddSimple("android:attr/foo", ResourceId(0x01050000)) + .AddSimple("android:attr/bar", ResourceId(0x01ff0006)) + .Add(NewResourceBuilder("android:attr/staged_baz") + .SetId(0x01ff0000) + .SetVisibility({.staged_api = true, .level = Visibility::Level::kPublic}) + .Build()) + .Build(); + IdAssigner assigner; + ASSERT_FALSE(assigner.Consume(context.get(), table.get())); +} + +TEST_F(IdAssignerTests, FailWhenTypeHaveBothStagedAndNonStagedIds) { + auto table = + test::ResourceTableBuilder() + .AddSimple("android:attr/foo", ResourceId(0x01010000)) + .Add(NewResourceBuilder("android:bool/staged_baz") + .SetId(0x01010001) + .SetVisibility({.staged_api = true, .level = Visibility::Level::kPublic}) + .Build()) + .Build(); IdAssigner assigner; ASSERT_FALSE(assigner.Consume(context.get(), table.get())); } diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp index 09a8560f984a..8143052f4376 100644 --- a/tools/aapt2/compile/PseudolocaleGenerator.cpp +++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp @@ -16,11 +16,15 @@ #include "compile/PseudolocaleGenerator.h" +#include <stdint.h> + #include <algorithm> +#include <random> #include "ResourceTable.h" #include "ResourceValues.h" #include "ValueVisitor.h" +#include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" #include "compile/Pseudolocalizer.h" #include "util/Util.h" @@ -293,8 +297,85 @@ class Visitor : public ValueVisitor { Pseudolocalizer localizer_; }; +class GrammaticalGenderVisitor : public ValueVisitor { + public: + std::unique_ptr<Value> value; + std::unique_ptr<Item> item; + + GrammaticalGenderVisitor(android::StringPool* pool, uint8_t grammaticalInflection) + : pool_(pool), grammaticalInflection_(grammaticalInflection) { + } + + void Visit(Plural* plural) override { + CloningValueTransformer cloner(pool_); + std::unique_ptr<Plural> grammatical_gendered = util::make_unique<Plural>(); + for (size_t i = 0; i < plural->values.size(); i++) { + if (plural->values[i]) { + GrammaticalGenderVisitor sub_visitor(pool_, grammaticalInflection_); + plural->values[i]->Accept(&sub_visitor); + if (sub_visitor.item) { + grammatical_gendered->values[i] = std::move(sub_visitor.item); + } else { + grammatical_gendered->values[i] = plural->values[i]->Transform(cloner); + } + } + } + grammatical_gendered->SetSource(plural->GetSource()); + grammatical_gendered->SetWeak(true); + value = std::move(grammatical_gendered); + } + + std::string AddGrammaticalGenderPrefix(const std::string_view& original_string) { + std::string result; + switch (grammaticalInflection_) { + case android::ResTable_config::GRAMMATICAL_GENDER_MASCULINE: + result = std::string("(M)") + std::string(original_string); + break; + case android::ResTable_config::GRAMMATICAL_GENDER_FEMININE: + result = std::string("(F)") + std::string(original_string); + break; + case android::ResTable_config::GRAMMATICAL_GENDER_NEUTER: + result = std::string("(N)") + std::string(original_string); + break; + default: + result = std::string(original_string); + break; + } + return result; + } + + void Visit(String* string) override { + std::string prefixed_string = AddGrammaticalGenderPrefix(std::string(*string->value)); + std::unique_ptr<String> grammatical_gendered = + util::make_unique<String>(pool_->MakeRef(prefixed_string)); + grammatical_gendered->SetSource(string->GetSource()); + grammatical_gendered->SetWeak(true); + item = std::move(grammatical_gendered); + } + + void Visit(StyledString* string) override { + std::string prefixed_string = AddGrammaticalGenderPrefix(std::string(string->value->value)); + android::StyleString new_string; + new_string.str = std::move(prefixed_string); + for (const android::StringPool::Span& span : string->value->spans) { + new_string.spans.emplace_back(android::Span{*span.name, span.first_char, span.last_char}); + } + std::unique_ptr<StyledString> grammatical_gendered = + util::make_unique<StyledString>(pool_->MakeRef(new_string)); + grammatical_gendered->SetSource(string->GetSource()); + grammatical_gendered->SetWeak(true); + item = std::move(grammatical_gendered); + } + + private: + DISALLOW_COPY_AND_ASSIGN(GrammaticalGenderVisitor); + android::StringPool* pool_; + uint8_t grammaticalInflection_; +}; + ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base, - Pseudolocalizer::Method m) { + Pseudolocalizer::Method m, + uint8_t grammaticalInflection) { ConfigDescription modified = base; switch (m) { case Pseudolocalizer::Method::kAccent: @@ -313,12 +394,64 @@ ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base, default: break; } + modified.grammaticalInflection = grammaticalInflection; return modified; } +void GrammaticalGender(ResourceConfigValue* original_value, + ResourceConfigValue* localized_config_value, android::StringPool* pool, + ResourceEntry* entry, const Pseudolocalizer::Method method, + uint8_t grammaticalInflection) { + GrammaticalGenderVisitor visitor(pool, grammaticalInflection); + localized_config_value->value->Accept(&visitor); + + std::unique_ptr<Value> grammatical_gendered_value; + if (visitor.value) { + grammatical_gendered_value = std::move(visitor.value); + } else if (visitor.item) { + grammatical_gendered_value = std::move(visitor.item); + } + if (!grammatical_gendered_value) { + return; + } + + ConfigDescription config = + ModifyConfigForPseudoLocale(original_value->config, method, grammaticalInflection); + + ResourceConfigValue* grammatical_gendered_config_value = + entry->FindOrCreateValue(config, original_value->product); + if (!grammatical_gendered_config_value->value) { + // Only use auto-generated pseudo-localization if none is defined. + grammatical_gendered_config_value->value = std::move(grammatical_gendered_value); + } +} + +const uint32_t MASK_MASCULINE = 1; // Bit mask for masculine +const uint32_t MASK_FEMININE = 2; // Bit mask for feminine +const uint32_t MASK_NEUTER = 4; // Bit mask for neuter + +void GrammaticalGenderIfNeeded(ResourceConfigValue* original_value, ResourceConfigValue* new_value, + android::StringPool* pool, ResourceEntry* entry, + const Pseudolocalizer::Method method, uint32_t gender_state) { + if (gender_state & MASK_FEMININE) { + GrammaticalGender(original_value, new_value, pool, entry, method, + android::ResTable_config::GRAMMATICAL_GENDER_FEMININE); + } + + if (gender_state & MASK_MASCULINE) { + GrammaticalGender(original_value, new_value, pool, entry, method, + android::ResTable_config::GRAMMATICAL_GENDER_MASCULINE); + } + + if (gender_state & MASK_NEUTER) { + GrammaticalGender(original_value, new_value, pool, entry, method, + android::ResTable_config::GRAMMATICAL_GENDER_NEUTER); + } +} + void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method, ResourceConfigValue* original_value, android::StringPool* pool, - ResourceEntry* entry) { + ResourceEntry* entry, uint32_t gender_state, bool gender_flag) { Visitor visitor(pool, method); original_value->value->Accept(&visitor); @@ -333,8 +466,8 @@ void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method, return; } - ConfigDescription config_with_accent = - ModifyConfigForPseudoLocale(original_value->config, method); + ConfigDescription config_with_accent = ModifyConfigForPseudoLocale( + original_value->config, method, android::ResTable_config::GRAMMATICAL_GENDER_ANY); ResourceConfigValue* new_config_value = entry->FindOrCreateValue(config_with_accent, original_value->product); @@ -342,6 +475,9 @@ void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method, // Only use auto-generated pseudo-localization if none is defined. new_config_value->value = std::move(localized_value); } + if (gender_flag) { + GrammaticalGenderIfNeeded(original_value, new_config_value, pool, entry, method, gender_state); + } } // A value is pseudolocalizable if it does not define a locale (or is the default locale) and is @@ -356,16 +492,71 @@ static bool IsPseudolocalizable(ResourceConfigValue* config_value) { } // namespace +bool ParseGenderValuesAndSaveState(const std::string& grammatical_gender_values, + uint32_t* gender_state, android::IDiagnostics* diag) { + std::vector<std::string> values = util::SplitAndLowercase(grammatical_gender_values, ','); + for (size_t i = 0; i < values.size(); i++) { + if (values[i].length() != 0) { + if (values[i] == "f") { + *gender_state |= MASK_FEMININE; + } else if (values[i] == "m") { + *gender_state |= MASK_MASCULINE; + } else if (values[i] == "n") { + *gender_state |= MASK_NEUTER; + } else { + diag->Error(android::DiagMessage() << "Invalid grammatical gender value: " << values[i]); + return false; + } + } + } + return true; +} + +bool ParseGenderRatio(const std::string& grammatical_gender_ratio, float* gender_ratio, + android::IDiagnostics* diag) { + const char* input = grammatical_gender_ratio.c_str(); + char* endPtr; + errno = 0; + *gender_ratio = strtof(input, &endPtr); + if (endPtr == input || *endPtr != '\0' || errno == ERANGE || *gender_ratio < 0 || + *gender_ratio > 1) { + diag->Error(android::DiagMessage() + << "Invalid grammatical gender ratio: " << grammatical_gender_ratio + << ", must be a real number between 0 and 1"); + return false; + } + return true; +} + bool PseudolocaleGenerator::Consume(IAaptContext* context, ResourceTable* table) { + uint32_t gender_state = 0; + if (!ParseGenderValuesAndSaveState(grammatical_gender_values_, &gender_state, + context->GetDiagnostics())) { + return false; + } + + float gender_ratio = 0; + if (!ParseGenderRatio(grammatical_gender_ratio_, &gender_ratio, context->GetDiagnostics())) { + return false; + } + + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution<> distrib(0.0, 1.0); + for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { + bool gender_flag = false; + if (distrib(gen) < gender_ratio) { + gender_flag = true; + } std::vector<ResourceConfigValue*> values = entry->FindValuesIf(IsPseudolocalizable); for (ResourceConfigValue* value : values) { PseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value, &table->string_pool, - entry.get()); + entry.get(), gender_state, gender_flag); PseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value, &table->string_pool, - entry.get()); + entry.get(), gender_state, gender_flag); } } } diff --git a/tools/aapt2/compile/PseudolocaleGenerator.h b/tools/aapt2/compile/PseudolocaleGenerator.h index 44e6e3e86f92..ce92008cdba1 100644 --- a/tools/aapt2/compile/PseudolocaleGenerator.h +++ b/tools/aapt2/compile/PseudolocaleGenerator.h @@ -27,8 +27,19 @@ std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string, Pseudolocalizer::Method method, android::StringPool* pool); -struct PseudolocaleGenerator : public IResourceTableConsumer { - bool Consume(IAaptContext* context, ResourceTable* table) override; +class PseudolocaleGenerator : public IResourceTableConsumer { + public: + explicit PseudolocaleGenerator(std::string grammatical_gender_values, + std::string grammatical_gender_ratio) + : grammatical_gender_values_(std::move(grammatical_gender_values)), + grammatical_gender_ratio_(std::move(grammatical_gender_ratio)) { + } + + bool Consume(IAaptContext* context, ResourceTable* table); + + private: + std::string grammatical_gender_values_; + std::string grammatical_gender_ratio_; }; } // namespace aapt diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp index 2f90cbf722c2..1477ebf8473d 100644 --- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp +++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp @@ -197,7 +197,7 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeOnlyDefaultConfigs) { val->SetTranslatable(false); std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); - PseudolocaleGenerator generator; + PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0")); ASSERT_TRUE(generator.Consume(context.get(), table.get())); // Normal pseudolocalization should take place. @@ -249,7 +249,7 @@ TEST(PseudolocaleGeneratorTest, PluralsArePseudolocalized) { expected->values = {util::make_unique<String>(table->string_pool.MakeRef("[žéŕö one]")), util::make_unique<String>(table->string_pool.MakeRef("[öñé one]"))}; - PseudolocaleGenerator generator; + PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0")); ASSERT_TRUE(generator.Consume(context.get(), table.get())); const auto* actual = test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", @@ -287,7 +287,7 @@ TEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) { context->GetDiagnostics())); } - PseudolocaleGenerator generator; + PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0")); ASSERT_TRUE(generator.Consume(context.get(), table.get())); StyledString* new_styled_string = test::GetValueForConfig<StyledString>( @@ -305,4 +305,213 @@ TEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) { EXPECT_NE(std::string::npos, new_string->value->find("world")); } +TEST(PseudolocaleGeneratorTest, PseudolocalizeGrammaticalGenderForString) { + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build(); + + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0")); + ASSERT_TRUE(generator.Consume(context.get(), table.get())); + + String* locale = test::GetValueForConfig<String>(table.get(), "android:string/foo", + test::ParseConfigOrDie("en-rXA")); + ASSERT_NE(nullptr, locale); + + // Grammatical gendered string + auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine"); + config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + String* feminine = + test::GetValueForConfig<String>(table.get(), "android:string/foo", config_feminine); + ASSERT_NE(nullptr, feminine); + EXPECT_EQ(std::string("(F)") + *locale->value, *feminine->value); + + auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine"); + config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + String* masculine = + test::GetValueForConfig<String>(table.get(), "android:string/foo", config_masculine); + ASSERT_NE(nullptr, masculine); + EXPECT_EQ(std::string("(M)") + *locale->value, *masculine->value); + + auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter"); + config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + String* neuter = + test::GetValueForConfig<String>(table.get(), "android:string/foo", config_neuter); + ASSERT_NE(nullptr, neuter); + EXPECT_EQ(std::string("(N)") + *locale->value, *neuter->value); +} + +TEST(PseudolocaleGeneratorTest, PseudolocalizeGrammaticalGenderForPlural) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder().Build(); + std::unique_ptr<Plural> plural = util::make_unique<Plural>(); + plural->values = {util::make_unique<String>(table->string_pool.MakeRef("zero")), + util::make_unique<String>(table->string_pool.MakeRef("one"))}; + ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.pkg:plurals/foo")) + .SetValue(std::move(plural)) + .Build(), + context->GetDiagnostics())); + PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0")); + ASSERT_TRUE(generator.Consume(context.get(), table.get())); + + Plural* actual = test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", + test::ParseConfigOrDie("en-rXA")); + ASSERT_NE(nullptr, actual); + + // Grammatical gendered Plural + auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine"); + config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + Plural* actual_feminine = + test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", config_feminine); + for (size_t i = 0; i < actual->values.size(); i++) { + if (actual->values[i]) { + String* locale = ValueCast<String>(actual->values[i].get()); + String* feminine = ValueCast<String>(actual_feminine->values[i].get()); + EXPECT_EQ(std::string("(F)") + *locale->value, *feminine->value); + } + } + + auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine"); + config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + Plural* actual_masculine = + test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", config_masculine); + ASSERT_NE(nullptr, actual_masculine); + for (size_t i = 0; i < actual->values.size(); i++) { + if (actual->values[i]) { + String* locale = ValueCast<String>(actual->values[i].get()); + String* masculine = ValueCast<String>(actual_masculine->values[i].get()); + EXPECT_EQ(std::string("(M)") + *locale->value, *masculine->value); + } + } + + auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter"); + config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + Plural* actual_neuter = + test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", config_neuter); + for (size_t i = 0; i < actual->values.size(); i++) { + if (actual->values[i]) { + String* locale = ValueCast<String>(actual->values[i].get()); + String* neuter = ValueCast<String>(actual_neuter->values[i].get()); + EXPECT_EQ(std::string("(N)") + *locale->value, *neuter->value); + } + } +} + +TEST(PseudolocaleGeneratorTest, PseudolocalizeGrammaticalGenderForStyledString) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder().Build(); + android::StyleString original_style; + original_style.str = "Hello world!"; + original_style.spans = {android::Span{"i", 1, 10}}; + + std::unique_ptr<StyledString> original = + util::make_unique<StyledString>(table->string_pool.MakeRef(original_style)); + ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/foo")) + .SetValue(std::move(original)) + .Build(), + context->GetDiagnostics())); + PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0")); + ASSERT_TRUE(generator.Consume(context.get(), table.get())); + + StyledString* locale = test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", + test::ParseConfigOrDie("en-rXA")); + ASSERT_NE(nullptr, locale); + EXPECT_EQ(1, locale->value->spans.size()); + EXPECT_EQ(std::string("i"), *locale->value->spans[0].name); + + // Grammatical gendered StyledString + auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine"); + config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + StyledString* feminine = + test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", config_feminine); + ASSERT_NE(nullptr, feminine); + EXPECT_EQ(1, feminine->value->spans.size()); + EXPECT_EQ(std::string("i"), *feminine->value->spans[0].name); + EXPECT_EQ(std::string("(F)") + locale->value->value, feminine->value->value); + + auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine"); + config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + StyledString* masculine = + test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", config_masculine); + ASSERT_NE(nullptr, masculine); + EXPECT_EQ(1, masculine->value->spans.size()); + EXPECT_EQ(std::string("i"), *masculine->value->spans[0].name); + EXPECT_EQ(std::string("(M)") + locale->value->value, masculine->value->value); + + auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter"); + config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + StyledString* neuter = + test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", config_neuter); + ASSERT_NE(nullptr, neuter); + EXPECT_EQ(1, neuter->value->spans.size()); + EXPECT_EQ(std::string("i"), *neuter->value->spans[0].name); + EXPECT_EQ(std::string("(N)") + locale->value->value, neuter->value->value); +} + +TEST(PseudolocaleGeneratorTest, GrammaticalGenderForCertainValues) { + // single gender value + std::unique_ptr<ResourceTable> table_0 = + test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build(); + + std::unique_ptr<IAaptContext> context_0 = test::ContextBuilder().Build(); + PseudolocaleGenerator generator_0(std::string("f"), std::string("1.0")); + ASSERT_TRUE(generator_0.Consume(context_0.get(), table_0.get())); + + String* locale_0 = test::GetValueForConfig<String>(table_0.get(), "android:string/foo", + test::ParseConfigOrDie("en-rXA")); + ASSERT_NE(nullptr, locale_0); + + auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine"); + config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + String* feminine_0 = + test::GetValueForConfig<String>(table_0.get(), "android:string/foo", config_feminine); + ASSERT_NE(nullptr, feminine_0); + EXPECT_EQ(std::string("(F)") + *locale_0->value, *feminine_0->value); + + auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine"); + config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + String* masculine_0 = + test::GetValueForConfig<String>(table_0.get(), "android:string/foo", config_masculine); + EXPECT_EQ(nullptr, masculine_0); + + auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter"); + config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY; + String* neuter_0 = + test::GetValueForConfig<String>(table_0.get(), "android:string/foo", config_neuter); + EXPECT_EQ(nullptr, neuter_0); + + // multiple gender values + std::unique_ptr<ResourceTable> table_1 = + test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build(); + + std::unique_ptr<IAaptContext> context_1 = test::ContextBuilder().Build(); + PseudolocaleGenerator generator_1(std::string("f,n"), std::string("1.0")); + ASSERT_TRUE(generator_1.Consume(context_1.get(), table_1.get())); + + String* locale_1 = test::GetValueForConfig<String>(table_1.get(), "android:string/foo", + test::ParseConfigOrDie("en-rXA")); + ASSERT_NE(nullptr, locale_1); + + String* feminine_1 = + test::GetValueForConfig<String>(table_1.get(), "android:string/foo", config_feminine); + ASSERT_NE(nullptr, feminine_1); + EXPECT_EQ(std::string("(F)") + *locale_1->value, *feminine_1->value); + + String* masculine_1 = + test::GetValueForConfig<String>(table_1.get(), "android:string/foo", config_masculine); + EXPECT_EQ(nullptr, masculine_1); + + String* neuter_1 = + test::GetValueForConfig<String>(table_1.get(), "android:string/foo", config_neuter); + ASSERT_NE(nullptr, neuter_1); + EXPECT_EQ(std::string("(N)") + *locale_1->value, *neuter_1->value); + + // invalid gender value + std::unique_ptr<ResourceTable> table_2 = + test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build(); + + std::unique_ptr<IAaptContext> context_2 = test::ContextBuilder().Build(); + PseudolocaleGenerator generator_2(std::string("invald,"), std::string("1.0")); + ASSERT_FALSE(generator_2.Consume(context_2.get(), table_2.get())); +} + } // namespace aapt diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index a43bf1b60f42..6bf265d2e363 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -837,9 +837,9 @@ class UsesSdkBadging : public ManifestExtractor::Element { void Print(text::Printer* printer) override { if (min_sdk) { - printer->Print(StringPrintf("sdkVersion:'%d'\n", *min_sdk)); + printer->Print(StringPrintf("minSdkVersion:'%d'\n", *min_sdk)); } else if (min_sdk_name) { - printer->Print(StringPrintf("sdkVersion:'%s'\n", min_sdk_name->data())); + printer->Print(StringPrintf("minSdkVersion:'%s'\n", min_sdk_name->data())); } if (max_sdk) { printer->Print(StringPrintf("maxSdkVersion:'%d'\n", *max_sdk)); diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp index 75dcba581c90..2e20e8175213 100644 --- a/tools/aapt2/format/binary/BinaryResourceParser.cpp +++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp @@ -453,7 +453,7 @@ bool BinaryResourceParser::ParseLibrary(const ResChunk_header* chunk) { const size_t count = entries.size(); for (size_t i = 0; i < count; i++) { table_->included_packages_[entries.valueAt(i)] = - android::util::Utf16ToUtf8(StringPiece16(entries.keyAt(i).string())); + android::util::Utf16ToUtf8(StringPiece16(entries.keyAt(i).c_str())); } return true; } diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp index 8c594ba553a0..f05611048caa 100644 --- a/tools/aapt2/format/binary/TableFlattener.cpp +++ b/tools/aapt2/format/binary/TableFlattener.cpp @@ -68,9 +68,8 @@ struct OverlayableChunk { class PackageFlattener { public: PackageFlattener(IAaptContext* context, const ResourceTablePackageView& package, - const std::map<size_t, std::string>* shared_libs, - SparseEntriesMode sparse_entries, - bool compact_entries, + const ResourceTable::ReferencedPackages* shared_libs, + SparseEntriesMode sparse_entries, bool compact_entries, bool collapse_key_stringpool, const std::set<ResourceName>& name_collapse_exemptions, bool deduplicate_entry_values) @@ -145,10 +144,9 @@ class PackageFlattener { // 2) the entries will be accessed on platforms U+, and // 3) all entry keys can be encoded in 16 bits bool UseCompactEntries(const ConfigDescription& config, std::vector<FlatEntry>* entries) const { - return compact_entries_ && - (context_->GetMinSdkVersion() > SDK_TIRAMISU || config.sdkVersion > SDK_TIRAMISU) && - std::none_of(entries->cbegin(), entries->cend(), - [](const auto& e) { return e.entry_key >= std::numeric_limits<uint16_t>::max(); }); + return compact_entries_ && context_->GetMinSdkVersion() > SDK_TIRAMISU && + std::none_of(entries->cbegin(), entries->cend(), + [](const auto& e) { return e.entry_key >= std::numeric_limits<uint16_t>::max(); }); } std::unique_ptr<ResEntryWriter> GetResEntryWriter(bool dedup, bool compact, BigBuffer* buffer) { @@ -548,7 +546,7 @@ class PackageFlattener { IAaptContext* context_; android::IDiagnostics* diag_; const ResourceTablePackageView package_; - const std::map<size_t, std::string>* shared_libs_; + const ResourceTable::ReferencedPackages* shared_libs_; SparseEntriesMode sparse_entries_; bool compact_entries_; android::StringPool type_pool_; diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp index 09ef9bddd3bd..e1a3013c07bb 100644 --- a/tools/aapt2/format/proto/ProtoDeserialize.cpp +++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp @@ -916,7 +916,7 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item, } break; case pb::Primitive::kIntDecimalValue: { val.dataType = android::Res_value::TYPE_INT_DEC; - val.data = static_cast<uint32_t>(pb_prim.int_decimal_value()); + val.data = static_cast<int32_t>(pb_prim.int_decimal_value()); } break; case pb::Primitive::kIntHexadecimalValue: { val.dataType = android::Res_value::TYPE_INT_HEX; diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp index afb83562b129..fa8860ff69eb 100644 --- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp @@ -250,6 +250,7 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) { } TEST(ProtoSerializeTest, SerializeAndDeserializeXml) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); xml::Element element; element.line_number = 22; element.column_number = 23; @@ -269,8 +270,8 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXml) { attr.namespace_uri = xml::kSchemaAndroid; attr.value = "23dp"; attr.compiled_attribute = xml::AaptAttribute(Attribute{}, ResourceId(0x01010000)); - attr.compiled_value = - ResourceUtils::TryParseItemForAttribute(attr.value, android::ResTable_map::TYPE_DIMENSION); + attr.compiled_value = ResourceUtils::TryParseItemForAttribute( + context->GetDiagnostics(), attr.value, android::ResTable_map::TYPE_DIMENSION); attr.compiled_value->SetSource(android::Source().WithLine(25)); element.attributes.push_back(std::move(attr)); diff --git a/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt b/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt index cc0b3bf5d2fb..d14e5fb5c477 100644 --- a/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt +++ b/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt @@ -1,5 +1,5 @@ package: name='com.aapt.app' versionCode='222' versionName='222' platformBuildVersionName='12' platformBuildVersionCode='32' compileSdkVersion='32' compileSdkVersionCodename='12' -sdkVersion:'22' +minSdkVersion:'22' targetSdkVersion:'32' application: label='App' icon='' feature-group: label='' diff --git a/tools/aapt2/integration-tests/DumpTest/components_expected.txt b/tools/aapt2/integration-tests/DumpTest/components_expected.txt index 9c81fb83ca15..93cce0a29024 100644 --- a/tools/aapt2/integration-tests/DumpTest/components_expected.txt +++ b/tools/aapt2/integration-tests/DumpTest/components_expected.txt @@ -1,5 +1,5 @@ package: name='com.example.bundletool.minimal' versionCode='1' versionName='1.0' platformBuildVersionName='12' platformBuildVersionCode='31' compileSdkVersion='31' compileSdkVersionCodename='12' -sdkVersion:'21' +minSdkVersion:'21' targetSdkVersion:'31' uses-configuration: reqTouchScreen='3' reqKeyboardType='2' reqHardKeyboard='-1' reqNavigation='3' reqFiveWayNav='-1' supports-gl-texture:'GL_OES_compressed_paletted_texture' diff --git a/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt b/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt index 85ab5d80cd39..aafca68443a9 100644 --- a/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt +++ b/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt @@ -1,5 +1,5 @@ package: name='com.lato.bubblegirl' versionCode='33' versionName='1.0.0' platformBuildVersionName='8.1.0' platformBuildVersionCode='27' -sdkVersion:'19' +minSdkVersion:'19' targetSdkVersion:'26' application-label:'Bubble Girl' application-label-ar:'Bubble Girl' diff --git a/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt b/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt index 85e8d0a3cbba..f48f381e3012 100644 --- a/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt +++ b/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt @@ -1,5 +1,5 @@ package: name='com.test.e17wmultiapknexus' versionCode='107' versionName='14' platformBuildVersionName='2.3.3' platformBuildVersionCode='10' -sdkVersion:'1' +minSdkVersion:'1' application-label:'w45wmultiapknexus_10' application-icon-120:'res/drawable-ldpi-v4/icon.png' application-icon-160:'res/drawable-mdpi-v4/icon.png' diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp index 9dadfb26a3f8..c69b32513167 100644 --- a/tools/aapt2/link/ReferenceLinker.cpp +++ b/tools/aapt2/link/ReferenceLinker.cpp @@ -164,8 +164,8 @@ std::unique_ptr<Item> ReferenceLinkerTransformer::TransformItem(const Reference* std::unique_ptr<Item> ReferenceLinkerTransformer::ParseValueWithAttribute( std::unique_ptr<Item> value, const Attribute* attr) { if (RawString* raw_string = ValueCast<RawString>(value.get())) { - std::unique_ptr<Item> transformed = - ResourceUtils::TryParseItemForAttribute(*raw_string->value, attr); + std::unique_ptr<Item> transformed = ResourceUtils::TryParseItemForAttribute( + context_->GetDiagnostics(), *raw_string->value, attr); // If we could not parse as any specific type, try a basic STRING. if (!transformed && (attr->type_mask & android::ResTable_map::TYPE_STRING)) { diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp index d2e9bd770a31..aec7ceb82c0f 100644 --- a/tools/aapt2/link/XmlReferenceLinker.cpp +++ b/tools/aapt2/link/XmlReferenceLinker.cpp @@ -90,7 +90,8 @@ class XmlVisitor : public xml::PackageAwareVisitor { attribute = &attr.compiled_attribute.value().attribute; } - attr.compiled_value = ResourceUtils::TryParseItemForAttribute(attr.value, attribute); + attr.compiled_value = ResourceUtils::TryParseItemForAttribute(context_->GetDiagnostics(), + attr.value, attribute); if (attr.compiled_value) { // With a compiledValue, we must resolve the reference and assign it an ID. attr.compiled_value->SetSource(source); diff --git a/tools/aapt2/optimize/Obfuscator.cpp b/tools/aapt2/optimize/Obfuscator.cpp index 8f12f735736e..903cdf852566 100644 --- a/tools/aapt2/optimize/Obfuscator.cpp +++ b/tools/aapt2/optimize/Obfuscator.cpp @@ -40,9 +40,9 @@ Obfuscator::Obfuscator(OptimizeOptions& optimizeOptions) collapse_key_stringpool_(optimizeOptions.table_flattener_options.collapse_key_stringpool) { } -std::string ShortenFileName(android::StringPiece file_path, int output_length) { +std::string Obfuscator::ShortenFileName(android::StringPiece file_path, int output_length) { std::size_t hash_num = std::hash<android::StringPiece>{}(file_path); - std::string result = ""; + std::string result; // Convert to (modified) base64 so that it is a proper file path. for (int i = 0; i < output_length; i++) { uint8_t sextet = hash_num & 0x3f; @@ -52,10 +52,33 @@ std::string ShortenFileName(android::StringPiece file_path, int output_length) { return result; } +static std::string RenameDisallowedFileNames(const std::string& file_name) { + // We are renaming shortened file names to make sure they not a reserved file name in Windows. + // See: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file. We are renaming + // "COM" and "LPT" too because we are appending a number in case of hash collisions; "COM1", + // "COM2", etc. are reserved names. + static const char* const reserved_windows_names[] = {"CON", "PRN", "AUX", "NUL", "COM", "LPT"}; + if (file_name.length() == 3) { + // Need to convert the file name to uppercase as Windows is case insensitive. E.g., "NuL", + // "nul", and "NUl" are also reserved. + std::string result_upper_cased(3, 0); + std::transform(file_name.begin(), file_name.end(), result_upper_cased.begin(), + [](unsigned char c) { return std::toupper(c); }); + for (auto reserved_windows_name : reserved_windows_names) { + if (result_upper_cased == reserved_windows_name) { + // Simple solution to make it a non-reserved name is to add an underscore + return "_" + file_name; + } + } + } + + return file_name; +} + // Return the optimal hash length such that at most 10% of resources collide in // their shortened path. // Reference: http://matt.might.net/articles/counting-hash-collisions/ -int OptimalShortenedLength(int num_resources) { +static int OptimalShortenedLength(int num_resources) { if (num_resources > 4000) { return 3; } else { @@ -63,8 +86,8 @@ int OptimalShortenedLength(int num_resources) { } } -std::string GetShortenedPath(android::StringPiece shortened_filename, - android::StringPiece extension, int collision_count) { +static std::string GetShortenedPath(android::StringPiece shortened_filename, + android::StringPiece extension, int collision_count) { std::string shortened_path = std::string("res/") += shortened_filename; if (collision_count > 0) { shortened_path += std::to_string(collision_count); @@ -82,9 +105,9 @@ struct PathComparator { } }; -static bool HandleShortenFilePaths(ResourceTable* table, - std::map<std::string, std::string>& shortened_path_map, - const std::set<ResourceName>& path_shorten_exemptions) { +bool Obfuscator::HandleShortenFilePaths(ResourceTable* table, + std::map<std::string, std::string>& shortened_path_map, + const std::set<ResourceName>& path_shorten_exemptions) { // used to detect collisions std::unordered_set<std::string> shortened_paths; std::set<FileReference*, PathComparator> file_refs; @@ -112,7 +135,8 @@ static bool HandleShortenFilePaths(ResourceTable* table, // Android detects ColorStateLists via pathname, skip res/color* if (util::StartsWith(res_subdir, "res/color")) continue; - std::string shortened_filename = ShortenFileName(*file_ref->path, num_chars); + std::string shortened_filename = + RenameDisallowedFileNames(ShortenFileName(*file_ref->path, num_chars)); int collision_count = 0; std::string shortened_path = GetShortenedPath(shortened_filename, extension, collision_count); while (shortened_paths.find(shortened_path) != shortened_paths.end()) { diff --git a/tools/aapt2/optimize/Obfuscator.h b/tools/aapt2/optimize/Obfuscator.h index 5ccf54383aae..79d7e088d1cc 100644 --- a/tools/aapt2/optimize/Obfuscator.h +++ b/tools/aapt2/optimize/Obfuscator.h @@ -53,7 +53,14 @@ class Obfuscator : public IResourceTableConsumer { const ResourceNamedType& type_name, const ResourceTableEntryView& entry, const android::base::function_ref<void(Result, const ResourceName&)> onObfuscate); + protected: + virtual std::string ShortenFileName(android::StringPiece file_path, int output_length); + private: + bool HandleShortenFilePaths(ResourceTable* table, + std::map<std::string, std::string>& shortened_path_map, + const std::set<ResourceName>& path_shorten_exemptions); + TableFlattenerOptions& options_; const bool shorten_resource_paths_; const bool collapse_key_stringpool_; diff --git a/tools/aapt2/optimize/Obfuscator_test.cpp b/tools/aapt2/optimize/Obfuscator_test.cpp index 940cf1096f92..c3429e0fc1d6 100644 --- a/tools/aapt2/optimize/Obfuscator_test.cpp +++ b/tools/aapt2/optimize/Obfuscator_test.cpp @@ -19,6 +19,7 @@ #include <map> #include <memory> #include <string> +#include <utility> #include "ResourceTable.h" #include "android-base/file.h" @@ -26,6 +27,7 @@ using ::aapt::test::GetValue; using ::testing::AnyOf; +using ::testing::Contains; using ::testing::Eq; using ::testing::HasSubstr; using ::testing::IsFalse; @@ -33,6 +35,10 @@ using ::testing::IsTrue; using ::testing::Not; using ::testing::NotNull; +namespace aapt { + +namespace { + android::StringPiece GetExtension(android::StringPiece path) { auto iter = std::find(path.begin(), path.end(), '.'); return android::StringPiece(iter, path.end() - iter); @@ -45,7 +51,22 @@ void FillTable(aapt::test::ResourceTableBuilder& builder, int start, int end) { } } -namespace aapt { +class FakeObfuscator : public Obfuscator { + public: + explicit FakeObfuscator(OptimizeOptions& optimize_options, + const std::unordered_map<std::string, std::string>& shortened_name_map) + : Obfuscator(optimize_options), shortened_name_map_(shortened_name_map) { + } + + protected: + std::string ShortenFileName(android::StringPiece file_path, int output_length) override { + return shortened_name_map_[std::string(file_path)]; + } + + private: + std::unordered_map<std::string, std::string> shortened_name_map_; + DISALLOW_COPY_AND_ASSIGN(FakeObfuscator); +}; TEST(ObfuscatorTest, FileRefPathsChangedInResourceTable) { std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); @@ -127,7 +148,7 @@ TEST(ObfuscatorTest, SkipPathShortenExemptions) { EXPECT_THAT(path_map.find("res/drawables/xmlfile2.xml"), Not(Eq(path_map.end()))); FileReference* ref = GetValue<FileReference>(table.get(), "android:drawable/xmlfile"); - EXPECT_THAT(ref, NotNull()); + ASSERT_THAT(ref, NotNull()); ASSERT_THAT(HasFailure(), IsFalse()); // The path of first drawable in exemption was not changed EXPECT_THAT("res/drawables/xmlfile.xml", Eq(*ref->path)); @@ -161,13 +182,78 @@ TEST(ObfuscatorTest, KeepExtensions) { ASSERT_THAT(path_map.find("res/drawable/xmlfile.xml"), Not(Eq(path_map.end()))); ASSERT_THAT(path_map.find("res/drawable/pngfile.png"), Not(Eq(path_map.end()))); - auto shortend_xml_path = path_map[original_xml_path]; - auto shortend_png_path = path_map[original_png_path]; - EXPECT_THAT(GetExtension(path_map[original_xml_path]), Eq(android::StringPiece(".xml"))); EXPECT_THAT(GetExtension(path_map[original_png_path]), Eq(android::StringPiece(".png"))); } +TEST(ObfuscatorTest, ShortenedToReservedWindowsNames) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + + std::string original_path_1 = "res/drawable/pngfile_1.png"; + std::string original_path_2 = "res/drawable/pngfile_2.png"; + std::string original_path_3 = "res/drawable/pngfile_3.png"; + std::string original_path_4 = "res/drawable/pngfile_4.png"; + std::string original_path_5 = "res/drawable/pngfile_5.png"; + std::string original_path_6 = "res/drawable/pngfile_6.png"; + std::string original_path_7 = "res/drawable/pngfile_7.png"; + std::string original_path_8 = "res/drawable/pngfile_8.png"; + std::string original_path_9 = "res/drawable/pngfile_9.png"; + + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .AddFileReference("android:drawable/pngfile_1", original_path_1) + .AddFileReference("android:drawable/pngfile_2", original_path_2) + .AddFileReference("android:drawable/pngfile_3", original_path_3) + .AddFileReference("android:drawable/pngfile_4", original_path_4) + .AddFileReference("android:drawable/pngfile_5", original_path_5) + .AddFileReference("android:drawable/pngfile_6", original_path_6) + .AddFileReference("android:drawable/pngfile_7", original_path_7) + .AddFileReference("android:drawable/pngfile_8", original_path_8) + .AddFileReference("android:drawable/pngfile_9", original_path_9) + .Build(); + + OptimizeOptions options{.shorten_resource_paths = true}; + std::map<std::string, std::string>& path_map = options.table_flattener_options.shortened_path_map; + auto obfuscator = FakeObfuscator( + options, + { + {original_path_1, "CON"}, + {original_path_2, "Prn"}, + {original_path_3, "AuX"}, + {original_path_4, "nul"}, + {original_path_5, "cOM"}, + {original_path_6, "lPt"}, + {original_path_7, "lPt"}, + {original_path_8, "lPt"}, // 6, 7, and 8 will be appended with a number to disambiguate + {original_path_9, "F0o"}, // This one is not reserved + }); + ASSERT_TRUE(obfuscator.Consume(context.get(), table.get())); + + // Expect that the path map is populated + ASSERT_THAT(path_map.find(original_path_1), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_2), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_3), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_4), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_5), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_6), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_7), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_8), Not(Eq(path_map.end()))); + ASSERT_THAT(path_map.find(original_path_9), Not(Eq(path_map.end()))); + + EXPECT_THAT(path_map[original_path_1], Eq("res/_CON.png")); + EXPECT_THAT(path_map[original_path_2], Eq("res/_Prn.png")); + EXPECT_THAT(path_map[original_path_3], Eq("res/_AuX.png")); + EXPECT_THAT(path_map[original_path_4], Eq("res/_nul.png")); + EXPECT_THAT(path_map[original_path_5], Eq("res/_cOM.png")); + EXPECT_THAT(path_map[original_path_9], Eq("res/F0o.png")); + + std::set<std::string> lpt_shortened_names{path_map[original_path_6], path_map[original_path_7], + path_map[original_path_8]}; + EXPECT_THAT(lpt_shortened_names, Contains("res/_lPt.png")); + EXPECT_THAT(lpt_shortened_names, Contains("res/_lPt1.png")); + EXPECT_THAT(lpt_shortened_names, Contains("res/_lPt2.png")); +} + TEST(ObfuscatorTest, DeterministicallyHandleCollisions) { std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); @@ -247,7 +333,9 @@ TEST(ObfuscatorTest, DumpIdResourceMap) { ASSERT_TRUE(Obfuscator(options).Consume(context.get(), table.get())); // Expect that the id resource name map is populated + ASSERT_THAT(id_resource_map.find(0x7f020000), Not(Eq(id_resource_map.end()))); EXPECT_THAT(id_resource_map.at(0x7f020000), Eq("mycolor")); + ASSERT_THAT(id_resource_map.find(0x7f030000), Not(Eq(id_resource_map.end()))); EXPECT_THAT(id_resource_map.at(0x7f030000), Eq("mystring")); EXPECT_THAT(id_resource_map.find(0x7f030001), Eq(id_resource_map.end())); EXPECT_THAT(id_resource_map.find(0x7f030002), Eq(id_resource_map.end())); @@ -300,17 +388,18 @@ TEST(ObfuscatorTest, WriteObfuscationMapInProtocolBufferFormat) { ASSERT_TRUE(obfuscator.Consume(test::ContextBuilder().Build().get(), getProtocolBufferTableUnderTest().get())); - obfuscator.WriteObfuscationMap("obfuscated_map.pb"); + const auto map_path = testing::TempDir() + "/obfuscated_map.pb"; + ASSERT_TRUE(obfuscator.WriteObfuscationMap(map_path)); std::string pbOut; - android::base::ReadFileToString("obfuscated_map.pb", &pbOut, false /* follow_symlinks */); + ASSERT_TRUE(android::base::ReadFileToString(map_path, &pbOut, false /* follow_symlinks */)); EXPECT_THAT(pbOut, HasSubstr("drawable/xmlfile.xml")); EXPECT_THAT(pbOut, HasSubstr("drawable/pngfile.png")); EXPECT_THAT(pbOut, HasSubstr("mycolor")); EXPECT_THAT(pbOut, HasSubstr("mystring")); pb::ResourceMappings resourceMappings; - EXPECT_THAT(resourceMappings.ParseFromString(pbOut), IsTrue()); - EXPECT_THAT(resourceMappings.collapsed_names().resource_names_size(), Eq(2)); + ASSERT_THAT(resourceMappings.ParseFromString(pbOut), IsTrue()); + ASSERT_THAT(resourceMappings.collapsed_names().resource_names_size(), Eq(2)); auto& resource_names = resourceMappings.collapsed_names().resource_names(); EXPECT_THAT(resource_names.at(0).name(), AnyOf(Eq("mycolor"), Eq("mystring"))); EXPECT_THAT(resource_names.at(1).name(), AnyOf(Eq("mycolor"), Eq("mystring"))); @@ -328,11 +417,14 @@ TEST(ObfuscatorTest, WriteObfuscatingMapWithNonEnabledOption) { ASSERT_TRUE(obfuscator.Consume(test::ContextBuilder().Build().get(), getProtocolBufferTableUnderTest().get())); - obfuscator.WriteObfuscationMap("obfuscated_map.pb"); + const auto map_path = testing::TempDir() + "/obfuscated_map.pb"; + ASSERT_TRUE(obfuscator.WriteObfuscationMap(map_path)); std::string pbOut; - android::base::ReadFileToString("obfuscated_map.pb", &pbOut, false /* follow_symlinks */); + ASSERT_TRUE(android::base::ReadFileToString(map_path, &pbOut, false /* follow_symlinks */)); ASSERT_THAT(pbOut, Eq("")); } +} // namespace + } // namespace aapt diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp index bca62da447b0..d78baf9ffeb4 100644 --- a/tools/aapt2/process/SymbolTable.cpp +++ b/tools/aapt2/process/SymbolTable.cpp @@ -220,15 +220,9 @@ std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::FindByName( bool AssetManagerSymbolSource::AddAssetPath(StringPiece path) { TRACE_CALL(); - if (std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path.data())) { + if (auto apk = ApkAssets::Load(path.data())) { apk_assets_.push_back(std::move(apk)); - - std::vector<const ApkAssets*> apk_assets; - for (const std::unique_ptr<const ApkAssets>& apk_asset : apk_assets_) { - apk_assets.push_back(apk_asset.get()); - } - - asset_manager_.SetApkAssets(apk_assets); + asset_manager_.SetApkAssets(apk_assets_); return true; } return false; @@ -251,7 +245,7 @@ bool AssetManagerSymbolSource::IsPackageDynamic(uint32_t packageId, return true; } - for (const std::unique_ptr<const ApkAssets>& assets : apk_assets_) { + for (auto&& assets : apk_assets_) { for (const std::unique_ptr<const android::LoadedPackage>& loaded_package : assets->GetLoadedArsc()->GetPackages()) { if (package_name == loaded_package->GetPackageName() && loaded_package->IsDynamic()) { @@ -266,10 +260,11 @@ bool AssetManagerSymbolSource::IsPackageDynamic(uint32_t packageId, static std::unique_ptr<SymbolTable::Symbol> LookupAttributeInTable( android::AssetManager2& am, ResourceId id) { using namespace android; - if (am.GetApkAssets().empty()) { + if (am.GetApkAssetsCount() == 0) { return {}; } + auto op = am.StartOperation(); auto bag_result = am.GetBag(id.id); if (!bag_result.has_value()) { return nullptr; diff --git a/tools/aapt2/process/SymbolTable.h b/tools/aapt2/process/SymbolTable.h index b09ff702ca58..36eb0bab6046 100644 --- a/tools/aapt2/process/SymbolTable.h +++ b/tools/aapt2/process/SymbolTable.h @@ -207,8 +207,8 @@ class AssetManagerSymbolSource : public ISymbolSource { } private: + std::vector<android::AssetManager2::ApkAssetsPtr> apk_assets_; android::AssetManager2 asset_manager_; - std::vector<std::unique_ptr<const android::ApkAssets>> apk_assets_; DISALLOW_COPY_AND_ASSIGN(AssetManagerSymbolSource); }; diff --git a/tools/aapt2/trace/TraceBuffer.cpp b/tools/aapt2/trace/TraceBuffer.cpp index da5373936306..0988c313b65b 100644 --- a/tools/aapt2/trace/TraceBuffer.cpp +++ b/tools/aapt2/trace/TraceBuffer.cpp @@ -36,116 +36,142 @@ constexpr char kBegin = 'B'; constexpr char kEnd = 'E'; struct TracePoint { + char type; pid_t tid; int64_t time; std::string tag; - char type; }; std::vector<TracePoint> traces; +bool enabled = true; +constinit std::chrono::steady_clock::time_point startTime = {}; int64_t GetTime() noexcept { auto now = std::chrono::steady_clock::now(); - return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count(); + if (startTime == decltype(tracebuffer::startTime){}) { + startTime = now; + } + return std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count(); } -} // namespace anonymous - -void AddWithTime(const std::string& tag, char type, int64_t time) noexcept { - TracePoint t = {getpid(), time, tag, type}; - traces.emplace_back(t); +void AddWithTime(std::string tag, char type, int64_t time) noexcept { + TracePoint t = {type, getpid(), time, std::move(tag)}; + traces.emplace_back(std::move(t)); } -void Add(const std::string& tag, char type) noexcept { - AddWithTime(tag, type, GetTime()); +void Add(std::string tag, char type) noexcept { + AddWithTime(std::move(tag), type, GetTime()); } - - - void Flush(const std::string& basePath) { - TRACE_CALL(); if (basePath.empty()) { return; } + BeginTrace(__func__); // We can't do much here, only record that it happened. - std::stringstream s; + std::ostringstream s; s << basePath << aapt::file::sDirSep << "report_aapt2_" << getpid() << ".json"; FILE* f = android::base::utf8::fopen(s.str().c_str(), "a"); if (f == nullptr) { return; } - for(const TracePoint& trace : traces) { - fprintf(f, "{\"ts\" : \"%" PRIu64 "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", " - "\"name\" : \"%s\" },\n", trace.time, trace.type, 0, trace.tid, trace.tag.c_str()); + // Wrap the trace in a JSON array [] to make Chrome/Perfetto UI handle it. + char delimiter = '['; + for (const TracePoint& trace : traces) { + fprintf(f, + "%c{\"ts\" : \"%" PRIu64 + "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", \"name\" : \"%s\" }\n", + delimiter, trace.time, trace.type, 0, trace.tid, trace.tag.c_str()); + delimiter = ','; + } + if (!traces.empty()) { + fprintf(f, "]"); } fclose(f); traces.clear(); } +} // namespace + } // namespace tracebuffer -void BeginTrace(const std::string& tag) { - tracebuffer::Add(tag, tracebuffer::kBegin); +void BeginTrace(std::string tag) { + if (!tracebuffer::enabled) return; + tracebuffer::Add(std::move(tag), tracebuffer::kBegin); +} + +void EndTrace(std::string tag) { + if (!tracebuffer::enabled) return; + tracebuffer::Add(std::move(tag), tracebuffer::kEnd); +} + +bool Trace::enable(bool value) { + return tracebuffer::enabled = value; } -void EndTrace() { - tracebuffer::Add("", tracebuffer::kEnd); +Trace::Trace(const char* tag) { + if (!tracebuffer::enabled) return; + tag_.assign(tag); + tracebuffer::Add(tag_, tracebuffer::kBegin); } -Trace::Trace(const std::string& tag) { - tracebuffer::Add(tag, tracebuffer::kBegin); +Trace::Trace(std::string tag) : tag_(std::move(tag)) { + if (!tracebuffer::enabled) return; + tracebuffer::Add(tag_, tracebuffer::kBegin); } -Trace::Trace(const std::string& tag, const std::vector<android::StringPiece>& args) { - std::stringstream s; +template <class SpanOfStrings> +std::string makeTag(std::string_view tag, const SpanOfStrings& args) { + std::ostringstream s; s << tag; - s << " "; - for (auto& arg : args) { - s << arg; - s << " "; + if (!args.empty()) { + for (const auto& arg : args) { + s << ' '; + s << arg; + } } - tracebuffer::Add(s.str(), tracebuffer::kBegin); + return std::move(s).str(); +} + +Trace::Trace(std::string_view tag, const std::vector<android::StringPiece>& args) { + if (!tracebuffer::enabled) return; + tag_ = makeTag(tag, args); + tracebuffer::Add(tag_, tracebuffer::kBegin); } Trace::~Trace() { - tracebuffer::Add("", tracebuffer::kEnd); + if (!tracebuffer::enabled) return; + tracebuffer::Add(std::move(tag_), tracebuffer::kEnd); } -FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag) - : basepath_(basepath) { - tracebuffer::Add(tag, tracebuffer::kBegin); +FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag) { + if (!Trace::enable(!basepath.empty())) return; + basepath_.assign(basepath); + tag_.assign(tag); + tracebuffer::Add(tag_, tracebuffer::kBegin); } -FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag, - const std::vector<android::StringPiece>& args) : basepath_(basepath) { - std::stringstream s; - s << tag; - s << " "; - for (auto& arg : args) { - s << arg; - s << " "; - } - tracebuffer::Add(s.str(), tracebuffer::kBegin); +FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag, + const std::vector<android::StringPiece>& args) { + if (!Trace::enable(!basepath.empty())) return; + basepath_.assign(basepath); + tag_ = makeTag(tag, args); + tracebuffer::Add(tag_, tracebuffer::kBegin); } -FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag, - const std::vector<std::string>& args) : basepath_(basepath){ - std::stringstream s; - s << tag; - s << " "; - for (auto& arg : args) { - s << arg; - s << " "; - } - tracebuffer::Add(s.str(), tracebuffer::kBegin); +FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag, + const std::vector<std::string>& args) { + if (!Trace::enable(!basepath.empty())) return; + basepath_.assign(basepath); + tag_ = makeTag(tag, args); + tracebuffer::Add(tag_, tracebuffer::kBegin); } FlushTrace::~FlushTrace() { - tracebuffer::Add("", tracebuffer::kEnd); + if (!tracebuffer::enabled) return; + tracebuffer::Add(std::move(tag_), tracebuffer::kEnd); tracebuffer::Flush(basepath_); } -} // namespace aapt - +} // namespace aapt diff --git a/tools/aapt2/trace/TraceBuffer.h b/tools/aapt2/trace/TraceBuffer.h index ba751dd72f41..f0333d1fe071 100644 --- a/tools/aapt2/trace/TraceBuffer.h +++ b/tools/aapt2/trace/TraceBuffer.h @@ -17,41 +17,50 @@ #ifndef AAPT_TRACEBUFFER_H #define AAPT_TRACEBUFFER_H +#include <androidfw/StringPiece.h> + #include <string> +#include <string_view> #include <vector> -#include <androidfw/StringPiece.h> - namespace aapt { // Record timestamps for beginning and end of a task and generate systrace json fragments. // This is an in-process ftrace which has the advantage of being platform independent. // These methods are NOT thread-safe since aapt2 is not multi-threaded. -// Convenience RIAA object to automatically finish an event when object goes out of scope. +// Convenience RAII object to automatically finish an event when object goes out of scope. class Trace { public: - Trace(const std::string& tag); - Trace(const std::string& tag, const std::vector<android::StringPiece>& args); - ~Trace(); + Trace(const char* tag); + Trace(std::string tag); + Trace(std::string_view tag, const std::vector<android::StringPiece>& args); + ~Trace(); + + static bool enable(bool value = true); + +private: + std::string tag_; }; // Manual markers. -void BeginTrace(const std::string& tag); -void EndTrace(); +void BeginTrace(std::string tag); +void EndTrace(std::string tag); // A main trace is required to flush events to disk. Events are formatted in systrace // json format. class FlushTrace { public: - explicit FlushTrace(const std::string& basepath, const std::string& tag); - explicit FlushTrace(const std::string& basepath, const std::string& tag, - const std::vector<android::StringPiece>& args); - explicit FlushTrace(const std::string& basepath, const std::string& tag, - const std::vector<std::string>& args); - ~FlushTrace(); + explicit FlushTrace(std::string_view basepath, std::string_view tag); + explicit FlushTrace(std::string_view basepath, std::string_view tag, + const std::vector<android::StringPiece>& args); + explicit FlushTrace(std::string_view basepath, std::string_view tag, + const std::vector<std::string>& args); + ~FlushTrace(); + private: std::string basepath_; + std::string tag_; }; #define TRACE_CALL() Trace __t(__func__) diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp index be877660ef72..3d83caf29bba 100644 --- a/tools/aapt2/util/Util.cpp +++ b/tools/aapt2/util/Util.cpp @@ -21,6 +21,7 @@ #include <string> #include <vector> +#include "android-base/parseint.h" #include "android-base/stringprintf.h" #include "android-base/strings.h" #include "androidfw/BigBuffer.h" @@ -229,14 +230,29 @@ std::string GetToolFingerprint() { static const char* const sMinorVersion = "19"; // The build id of aapt2 binary. - static std::string sBuildId = android::build::GetBuildNumber(); - - if (android::base::StartsWith(sBuildId, "eng.")) { - time_t now = time(0); - tm* ltm = localtime(&now); + static const std::string sBuildId = [] { + std::string buildNumber = android::build::GetBuildNumber(); + + if (android::base::StartsWith(buildNumber, "eng.")) { + // android::build::GetBuildNumber() returns something like "eng.user.20230725.214219" where + // the latter two parts are "yyyyMMdd.HHmmss" at build time. Use "yyyyMM" in the fingerprint. + std::vector<std::string> parts = util::Split(buildNumber, '.'); + int buildYear; + int buildMonth; + if (parts.size() < 3 || parts[2].length() < 6 || + !android::base::ParseInt(parts[2].substr(0, 4), &buildYear) || + !android::base::ParseInt(parts[2].substr(4, 2), &buildMonth)) { + // Fallback to localtime() if GetBuildNumber() returns an unexpected output. + time_t now = time(0); + tm* ltm = localtime(&now); + buildYear = 1900 + ltm->tm_year; + buildMonth = 1 + ltm->tm_mon; + } - sBuildId = android::base::StringPrintf("eng.%d%d", 1900 + ltm->tm_year, 1 + ltm->tm_mon); - } + buildNumber = android::base::StringPrintf("eng.%04d%02d", buildYear, buildMonth); + } + return buildNumber; + }(); return android::base::StringPrintf("%s.%s-%s", sMajorVersion, sMinorVersion, sBuildId.c_str()); } diff --git a/tools/hiddenapi/OWNERS b/tools/hiddenapi/OWNERS index afbeef5a0b41..dc82aac9d41c 100644 --- a/tools/hiddenapi/OWNERS +++ b/tools/hiddenapi/OWNERS @@ -1,5 +1,4 @@ # compat-team@ for changes to hiddenapi files -andreionea@google.com mathewi@google.com satayev@google.com diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp index dd266ffe0f16..a2c1d6b4f784 100644 --- a/tools/incident_section_gen/main.cpp +++ b/tools/incident_section_gen/main.cpp @@ -383,13 +383,11 @@ static bool generatePrivacyFlags(const Descriptor* descriptor, const Destination if (allDefaults) return false; emptyline(); - int policyCount = 0; printf("Privacy* %s[] = {\n", messageName.c_str()); for (size_t i=0; i<fieldsInOrder.size(); i++) { const FieldDescriptor* field = fieldsInOrder[i]; if (hasDefaultFlags[i]) continue; // NOLINT(clang-analyzer-core.uninitialized.Branch) printf(" &%s,\n", getFieldName(field).c_str()); - policyCount++; } printf(" NULL };\n"); emptyline(); diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt index dcfbe953f955..f1727b78f135 100644 --- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt @@ -30,6 +30,7 @@ const val BINDER_CLASS = "android.os.Binder" const val IINTERFACE_INTERFACE = "android.os.IInterface" const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission" +const val PERMISSION_PREFIX_LITERAL = "android.permission." /** * If a non java (e.g. c++) backend is enabled, the @EnforcePermission @@ -72,5 +73,78 @@ val EXCLUDED_CPP_INTERFACES = listOf( "Status", "IThermalService", "IPowerManager", - "ITunerResourceManager" + "ITunerResourceManager", + // b/278147400 + "IActivityManager", + "IUidObserver", + "IDrm", + "IVsyncCallback", + "IVsyncService", + "ICallback", + "IIPCTest", + "ISafeInterfaceTest", + "IGpuService", + "IConsumerListener", + "IGraphicBufferConsumer", + "ITransactionComposerListener", + "SensorEventConnection", + "SensorServer", + "ICamera", + "ICameraClient", + "ICameraRecordingProxy", + "ICameraRecordingProxyListener", + "ICrypto", + "IOMXObserver", + "IStreamListener", + "IStreamSource", + "IAudioService", + "IDataSource", + "IDrmClient", + "IMediaCodecList", + "IMediaDrmService", + "IMediaExtractor", + "IMediaExtractorService", + "IMediaHTTPConnection", + "IMediaHTTPService", + "IMediaLogService", + "IMediaMetadataRetriever", + "IMediaMetricsService", + "IMediaPlayer", + "IMediaPlayerClient", + "IMediaPlayerService", + "IMediaRecorder", + "IMediaRecorderClient", + "IMediaResourceMonitor", + "IMediaSource", + "IRemoteDisplay", + "IRemoteDisplayClient", + "IResourceManagerClient", + "IResourceManagerService", + "IComplexTypeInterface", + "IPermissionController", + "IPingResponder", + "IProcessInfoService", + "ISchedulingPolicyService", + "IStringConstants", + "IObbActionListener", + "IStorageEventListener", + "IStorageManager", + "IStorageShutdownObserver", + "IPersistentVrStateCallbacks", + "IVrManager", + "IVrStateCallbacks", + "ISurfaceComposer", + "IMemory", + "IMemoryHeap", + "IProcfsInspector", + "IAppOpsCallback", + "IAppOpsService", + "IBatteryStats", + "IResultReceiver", + "IShellCallback", + "IDrmManagerService", + "IDrmServiceListener", + "IAAudioClient", + "IAAudioService", + "VtsFuzzer", ) diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt index 0baac2c7aacf..3a95df9b2773 100644 --- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt @@ -40,6 +40,8 @@ import org.jetbrains.uast.UElement import org.jetbrains.uast.UMethod import org.jetbrains.uast.toUElement +import java.util.EnumSet + /** * Lint Detector that ensures that any method overriding a method annotated * with @EnforcePermission is also annotated with the exact same annotation. @@ -93,7 +95,7 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { val v1 = ConstantEvaluator.evaluate(context, value1) val v2 = ConstantEvaluator.evaluate(context, value2) if (v1 != null && v2 != null) { - if (v1 != v2) { + if (v1 != v2 && !isOneShortPermissionOfOther(v1, v2)) { return false } } else { @@ -105,7 +107,7 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { for (j in children1.indices) { val c1 = ConstantEvaluator.evaluate(context, children1[j]) val c2 = ConstantEvaluator.evaluate(context, children2[j]) - if (c1 != c2) { + if (c1 != c2 && !isOneShortPermissionOfOther(c1, c2)) { return false } } @@ -114,6 +116,12 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { return true } + private fun isOneShortPermissionOfOther( + permission1: Any?, + permission2: Any? + ): Boolean = permission1 == (permission2 as? String)?.removePrefix(PERMISSION_PREFIX_LITERAL) || + permission2 == (permission1 as? String)?.removePrefix(PERMISSION_PREFIX_LITERAL) + private fun compareMethods( context: JavaContext, element: UElement, @@ -206,7 +214,7 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { severity = Severity.ERROR, implementation = Implementation( EnforcePermissionDetector::class.java, - Scope.JAVA_FILE_SCOPE + EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES) ) ) @@ -219,7 +227,7 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { severity = Severity.ERROR, implementation = Implementation( EnforcePermissionDetector::class.java, - Scope.JAVA_FILE_SCOPE + EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES) ) ) } diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt index df13af516514..cbbf91b49ded 100644 --- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt @@ -34,6 +34,8 @@ import org.jetbrains.uast.UExpression import org.jetbrains.uast.UMethod import org.jetbrains.uast.skipParenthesizedExprDown +import java.util.EnumSet + class EnforcePermissionHelperDetector : Detector(), SourceCodeScanner { override fun getApplicableUastTypes(): List<Class<out UElement?>> = listOf(UMethod::class.java) @@ -117,7 +119,7 @@ class EnforcePermissionHelperDetector : Detector(), SourceCodeScanner { severity = Severity.ERROR, implementation = Implementation( EnforcePermissionHelperDetector::class.java, - Scope.JAVA_FILE_SCOPE + EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES) ) ) @@ -130,7 +132,7 @@ class EnforcePermissionHelperDetector : Detector(), SourceCodeScanner { severity = Severity.ERROR, implementation = Implementation( EnforcePermissionDetector::class.java, - Scope.JAVA_FILE_SCOPE + EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES) ) ) diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt index c7be36efd991..22f749eee36b 100644 --- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt @@ -53,10 +53,9 @@ class SimpleManualPermissionEnforcementDetector : AidlImplementationDetector() { lintFix ) - // TODO(b/265014041): turn on errors once all code that would cause one is fixed - // if (enforcePermissionFix.errorLevel) { - // incident.overrideSeverity(Severity.ERROR) - // } + if (enforcePermissionFix.errorLevel) { + incident.overrideSeverity(Severity.ERROR) + } context.report(incident) } diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt index 75b00737a168..b3dacbdf57a6 100644 --- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt @@ -316,20 +316,55 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { overrides the method Stub.testMethod which is annotated with @EnforcePermission. The same annotation must be used on Default.testMethod [MissingEnforcePermissionAnnotation] public void testMethod() {} ~~~~~~~~~~ - 1 errors, 0 warnings + 1 errors, 0 warnings """.addLineContinuation() ) } - fun testDoesDetectIssuesShortStringsNotAllowed() { + fun testDoesNotDetectIssuesShortStringsAllowedInChildAndParent() { lint().files(java( """ package test.pkg; import android.annotation.EnforcePermission; public class TestClass121 extends IFooMethod.Stub { @Override + @EnforcePermission("READ_PHONE_STATE") + public void testMethod() {} + @Override + @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) + public void testMethodParentShortPermission() {} + @Override @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) public void testMethodAnyLiteral() {} + @Override + @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) + public void testMethodAnyLiteralParentsShortPermission() {} + } + """).indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testDoesDetectIssuesWrongShortStringsInChildAndParent() { + lint().files(java( + """ + package test.pkg; + import android.annotation.EnforcePermission; + public class TestClass121 extends IFooMethod.Stub { + @Override + @EnforcePermission("READ_WRONG_PHONE_STATE") + public void testMethod() {} + @Override + @EnforcePermission(android.Manifest.permission.READ_WRONG_PHONE_STATE) + public void testMethodParentShortPermission() {} + @Override + @EnforcePermission(anyOf={"WRONG_INTERNET", "READ_PHONE_STATE"}) + public void testMethodAnyLiteral() {} + @Override + @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_WRONG_PHONE_STATE}) + public void testMethodAnyLiteralParentsShortPermission() {} } """).indented(), *stubs @@ -337,14 +372,19 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .run() .expect( """ - src/test/pkg/TestClass121.java:6: Error: The method \ - TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) \ - which differs from the overridden method Stub.testMethodAnyLiteral: \ - @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \ - The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethodAnyLiteral() {} - ~~~~~~~~~~~~~~~~~~~~ - 1 errors, 0 warnings + src/test/pkg/TestClass121.java:6: Error: The method TestClass121.testMethod is annotated with @EnforcePermission("READ_WRONG_PHONE_STATE") which differs from the overridden method Stub.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethod() {} + ~~~~~~~~~~ + src/test/pkg/TestClass121.java:9: Error: The method TestClass121.testMethodParentShortPermission is annotated with @EnforcePermission(android.Manifest.permission.READ_WRONG_PHONE_STATE) which differs from the overridden method Stub.testMethodParentShortPermission: @android.annotation.EnforcePermission("READ_PHONE_STATE"). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethodParentShortPermission() {} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/test/pkg/TestClass121.java:12: Error: The method TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"WRONG_INTERNET", "READ_PHONE_STATE"}) which differs from the overridden method Stub.testMethodAnyLiteral: @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethodAnyLiteral() {} + ~~~~~~~~~~~~~~~~~~~~ + src/test/pkg/TestClass121.java:15: Error: The method TestClass121.testMethodAnyLiteralParentsShortPermission is annotated with @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_WRONG_PHONE_STATE}) which differs from the overridden method Stub.testMethodAnyLiteralParentsShortPermission: @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethodAnyLiteralParentsShortPermission() {} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 4 errors, 0 warnings """.addLineContinuation() ) } @@ -360,12 +400,18 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) public void testMethod() {} @Override + @android.annotation.EnforcePermission("READ_PHONE_STATE") + public void testMethodParentShortPermission() {} + @Override @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) public void testMethodAny() {} @Override @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) public void testMethodAnyLiteral() {} @Override + @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) + public void testMethodAnyLiteralParentsShortPermission() {} + @Override @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) public void testMethodAll() {} @Override @@ -374,10 +420,14 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { } @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) public void testMethod(); + @android.annotation.EnforcePermission("READ_PHONE_STATE") + public void testMethodParentShortPermission(); @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) public void testMethodAny() {} @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) public void testMethodAnyLiteral() {} + @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) + public void testMethodAnyLiteralParentsShortPermission() {} @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) public void testMethodAll() {} @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) @@ -404,6 +454,7 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package android.Manifest; class permission { public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; + public static final String READ_WRONG_PHONE_STATE = "android.permission.READ_WRONG_PHONE_STATE"; public static final String NFC = "android.permission.NFC"; public static final String INTERNET = "android.permission.INTERNET"; } diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt index 6b8e72cf9222..9170e752934f 100644 --- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt @@ -51,10 +51,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:7: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:7: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission("android.permission.READ_CONTACTS", "foo"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -168,10 +168,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:8: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:8: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission( ^ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -209,10 +209,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:8: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:8: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_CONTACTS, "foo"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -252,10 +252,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:10: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:10: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission( ^ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -414,10 +414,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:14: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:14: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] helper(); ~~~~~~~~~ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -506,10 +506,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:16: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:16: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission("FOO", "foo"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -558,10 +558,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:19: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:19: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] helperHelper(); ~~~~~~~~~~~~~~~ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( @@ -599,10 +599,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:7: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] + src/Foo.java:7: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] if (mContext.checkCallingOrSelfPermission("android.permission.READ_CONTACTS", "foo") ^ - 0 errors, 1 warnings + 1 errors, 0 warnings """ ) .expectFixDiffs( diff --git a/tools/protologtool/Android.bp b/tools/protologtool/Android.bp index 039bb4e2788c..46745e995f64 100644 --- a/tools/protologtool/Android.bp +++ b/tools/protologtool/Android.bp @@ -11,7 +11,7 @@ java_library_host { name: "protologtool-lib", srcs: [ "src/com/android/protolog/tool/**/*.kt", - ":protolog-common-src", + ":protolog-common-no-android-src", ], static_libs: [ "javaparser", diff --git a/tools/split-select/Android.bp b/tools/split-select/Android.bp index 540265793de6..ec9d42a2dc64 100644 --- a/tools/split-select/Android.bp +++ b/tools/split-select/Android.bp @@ -57,9 +57,6 @@ cc_defaults { // This tool is prebuilt if we're doing an app-only build. product_variables: { - pdk: { - enabled: false, - }, unbundled_build: { enabled: false, }, diff --git a/tools/split-select/Grouper_test.cpp b/tools/split-select/Grouper_test.cpp index 7294a86fa862..a8b78cd3cf7c 100644 --- a/tools/split-select/Grouper_test.cpp +++ b/tools/split-select/Grouper_test.cpp @@ -179,7 +179,7 @@ void GrouperTest::expectHasGroupWithSplits(const Vector<const char*>& expectedSt errorMessage.append("\n"); } } - ADD_FAILURE() << errorMessage.string(); + ADD_FAILURE() << errorMessage.c_str(); } void GrouperTest::addSplit(Vector<SplitDescription>& splits, const char* str) { diff --git a/tools/split-select/Main.cpp b/tools/split-select/Main.cpp index e6966db0aa00..1e751171b370 100644 --- a/tools/split-select/Main.cpp +++ b/tools/split-select/Main.cpp @@ -99,8 +99,7 @@ void generate(const KeyedVector<String8, Vector<SplitDescription> >& splits, con } masterRule = Rule::simplify(masterRule); fprintf(stdout, " {\n \"path\": \"%s\",\n \"rules\": %s\n }", - splits.keyAt(i).string(), - masterRule->toJson(2).string()); + splits.keyAt(i).c_str(), masterRule->toJson(2).c_str()); } fprintf(stdout, "\n]\n"); } @@ -158,25 +157,23 @@ static bool getAppInfo(const String8& path, AppInfo& outInfo) { const char16_t* name = xml.getElementName(&len); String16 name16(name, len); if (name16 == kManifestTag) { - ssize_t idx = xml.indexOfAttribute( - kAndroidNamespace.string(), kAndroidNamespace.size(), - kVersionCodeAttr.string(), kVersionCodeAttr.size()); + ssize_t idx = xml.indexOfAttribute(kAndroidNamespace.c_str(), kAndroidNamespace.size(), + kVersionCodeAttr.c_str(), kVersionCodeAttr.size()); if (idx >= 0) { outInfo.versionCode = xml.getAttributeData(idx); } } else if (name16 == kApplicationTag) { - ssize_t idx = xml.indexOfAttribute( - kAndroidNamespace.string(), kAndroidNamespace.size(), - kMultiArchAttr.string(), kMultiArchAttr.size()); + ssize_t idx = xml.indexOfAttribute(kAndroidNamespace.c_str(), kAndroidNamespace.size(), + kMultiArchAttr.c_str(), kMultiArchAttr.size()); if (idx >= 0) { outInfo.multiArch = xml.getAttributeData(idx) != 0; } } else if (name16 == kUsesSdkTag) { - ssize_t idx = xml.indexOfAttribute( - kAndroidNamespace.string(), kAndroidNamespace.size(), - kMinSdkVersionAttr.string(), kMinSdkVersionAttr.size()); + ssize_t idx = + xml.indexOfAttribute(kAndroidNamespace.c_str(), kAndroidNamespace.size(), + kMinSdkVersionAttr.c_str(), kMinSdkVersionAttr.size()); if (idx >= 0) { uint16_t type = xml.getAttributeDataType(idx); if (type >= Res_value::TYPE_FIRST_INT && type <= Res_value::TYPE_LAST_INT) { @@ -187,10 +184,10 @@ static bool getAppInfo(const String8& path, AppInfo& outInfo) { fprintf(stderr, "warning: failed to retrieve android:minSdkVersion.\n"); } else { char *endPtr; - int minSdk = strtol(minSdk8->string(), &endPtr, 10); - if (endPtr != minSdk8->string() + minSdk8->size()) { + int minSdk = strtol(minSdk8->c_str(), &endPtr, 10); + if (endPtr != minSdk8->c_str() + minSdk8->size()) { fprintf(stderr, "warning: failed to parse android:minSdkVersion '%s'\n", - minSdk8->string()); + minSdk8->c_str()); } else { outInfo.minSdkVersion = minSdk; } @@ -232,7 +229,7 @@ static Vector<SplitDescription> extractSplitDescriptionsFromApk(const String8& p splits.add(); Vector<String8> parts = AaptUtil::splitAndLowerCase(dir->getFileName(i), '-'); if (parseAbi(parts, 0, &splits.editTop()) < 0) { - fprintf(stderr, "Malformed library %s\n", dir->getFileName(i).string()); + fprintf(stderr, "Malformed library %s\n", dir->getFileName(i).c_str()); splits.pop(); } } @@ -291,7 +288,7 @@ static int main(int argc, char** argv) { help(); return 0; } else { - fprintf(stderr, "error: unknown argument '%s'.\n", arg.string()); + fprintf(stderr, "error: unknown argument '%s'.\n", arg.c_str()); usage(); return 1; } @@ -313,15 +310,14 @@ static int main(int argc, char** argv) { // Find out some details about the base APK. AppInfo baseAppInfo; if (!getAppInfo(baseApkPath, baseAppInfo)) { - fprintf(stderr, "error: unable to read base APK: '%s'.\n", baseApkPath.string()); + fprintf(stderr, "error: unable to read base APK: '%s'.\n", baseApkPath.c_str()); return 1; } SplitDescription targetSplit; if (!generateFlag) { if (!SplitDescription::parse(targetConfigStr, &targetSplit)) { - fprintf(stderr, "error: invalid --target config: '%s'.\n", - targetConfigStr.string()); + fprintf(stderr, "error: invalid --target config: '%s'.\n", targetConfigStr.c_str()); usage(); return 1; } @@ -341,7 +337,7 @@ static int main(int argc, char** argv) { Vector<SplitDescription> splits = extractSplitDescriptionsFromApk(splitApkPaths[i]); if (splits.isEmpty()) { fprintf(stderr, "error: invalid --split path: '%s'. No splits found.\n", - splitApkPaths[i].string()); + splitApkPaths[i].c_str()); usage(); return 1; } @@ -364,7 +360,7 @@ static int main(int argc, char** argv) { const size_t matchingSplitApkPathCount = matchingSplitPaths.size(); for (size_t i = 0; i < matchingSplitApkPathCount; i++) { if (matchingSplitPaths[i] != baseApkPath) { - fprintf(stdout, "%s\n", matchingSplitPaths[i].string()); + fprintf(stdout, "%s\n", matchingSplitPaths[i].c_str()); } } } else { diff --git a/tools/split-select/Rule_test.cpp b/tools/split-select/Rule_test.cpp index c6cff0d0220e..c78533fd1907 100644 --- a/tools/split-select/Rule_test.cpp +++ b/tools/split-select/Rule_test.cpp @@ -68,7 +68,7 @@ TEST(RuleTest, generatesValidJson) { expected.erase(std::remove_if(expected.begin(), expected.end(), ::isspace), expected.end()); // Result - std::string result(rule.toJson().string()); + std::string result(rule.toJson().c_str()); result.erase(std::remove_if(result.begin(), result.end(), ::isspace), result.end()); ASSERT_EQ(expected, result); diff --git a/tools/split-select/SplitDescription.cpp b/tools/split-select/SplitDescription.cpp index 99bc23d819fb..4e2b48e1f450 100644 --- a/tools/split-select/SplitDescription.cpp +++ b/tools/split-select/SplitDescription.cpp @@ -134,8 +134,8 @@ bool SplitDescription::parse(const String8& str, SplitDescription* outSplit) { String8 configStr; String8 extensionStr; if (index >= 0) { - configStr.setTo(str.string(), index); - extensionStr.setTo(str.string() + index + 1); + configStr.setTo(str.c_str(), index); + extensionStr.setTo(str.c_str() + index + 1); } else { configStr.setTo(str); } diff --git a/tools/split-select/TestRules.cpp b/tools/split-select/TestRules.cpp index 86ccd6a25c18..ca3c56fe861c 100644 --- a/tools/split-select/TestRules.cpp +++ b/tools/split-select/TestRules.cpp @@ -78,9 +78,8 @@ const Rule AlwaysTrue() { const String8 actualStr(actual != NULL ? actual->toJson() : String8()); if (expectedStr != actualStr) { - return ::testing::AssertionFailure() - << "Expected: " << expectedStr.string() << "\n" - << " Actual: " << actualStr.string(); + return ::testing::AssertionFailure() << "Expected: " << expectedStr.c_str() << "\n" + << " Actual: " << actualStr.c_str(); } return ::testing::AssertionSuccess(); } diff --git a/tools/streaming_proto/OWNERS b/tools/streaming_proto/OWNERS new file mode 100644 index 000000000000..5f6e59f82c8a --- /dev/null +++ b/tools/streaming_proto/OWNERS @@ -0,0 +1 @@ +mwachens@google.com diff --git a/tools/streaming_proto/cpp/main.cpp b/tools/streaming_proto/cpp/main.cpp index fe9a438d81d7..905ed354049b 100644 --- a/tools/streaming_proto/cpp/main.cpp +++ b/tools/streaming_proto/cpp/main.cpp @@ -119,9 +119,8 @@ write_message(stringstream& text, const DescriptorProto& message, const string& text << endl; } -static void -write_header_file(CodeGeneratorResponse* response, const FileDescriptorProto& file_descriptor) -{ +static void write_header_file(const string& request_parameter, CodeGeneratorResponse* response, + const FileDescriptorProto& file_descriptor) { stringstream text; text << "// Generated by protoc-gen-cppstream. DO NOT MODIFY." << endl; @@ -159,6 +158,9 @@ write_header_file(CodeGeneratorResponse* response, const FileDescriptorProto& fi text << endl; text << "#endif // " << header << endl; + if (request_parameter.find("experimental_allow_proto3_optional") != string::npos) { + response->set_supported_features(CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL); + } CodeGeneratorResponse::File* file_response = response->add_file(); file_response->set_name(make_filename(file_descriptor)); file_response->set_content(text.str()); @@ -182,7 +184,7 @@ int main(int argc, char const *argv[]) for (int i=0; i<N; i++) { const FileDescriptorProto& file_descriptor = request.proto_file(i); if (should_generate_for_file(request, file_descriptor.name())) { - write_header_file(&response, file_descriptor); + write_header_file(request.parameter(), &response, file_descriptor); } } diff --git a/tools/xmlpersistence/Android.bp b/tools/xmlpersistence/Android.bp deleted file mode 100644 index 0b6dba626794..000000000000 --- a/tools/xmlpersistence/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -java_binary_host { - name: "xmlpersistence_cli", - manifest: "manifest.txt", - srcs: [ - "src/**/*.kt", - ], - static_libs: [ - "javaparser-symbol-solver", - "javapoet", - ], -} diff --git a/tools/xmlpersistence/OWNERS b/tools/xmlpersistence/OWNERS deleted file mode 100644 index 4f4d06a32676..000000000000 --- a/tools/xmlpersistence/OWNERS +++ /dev/null @@ -1 +0,0 @@ -zhanghai@google.com diff --git a/tools/xmlpersistence/manifest.txt b/tools/xmlpersistence/manifest.txt deleted file mode 100644 index 6d9771998efc..000000000000 --- a/tools/xmlpersistence/manifest.txt +++ /dev/null @@ -1 +0,0 @@ -Main-class: MainKt diff --git a/tools/xmlpersistence/src/main/kotlin/Generator.kt b/tools/xmlpersistence/src/main/kotlin/Generator.kt deleted file mode 100644 index 8e62388c860f..000000000000 --- a/tools/xmlpersistence/src/main/kotlin/Generator.kt +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.squareup.javapoet.ClassName -import com.squareup.javapoet.FieldSpec -import com.squareup.javapoet.JavaFile -import com.squareup.javapoet.MethodSpec -import com.squareup.javapoet.NameAllocator -import com.squareup.javapoet.ParameterSpec -import com.squareup.javapoet.TypeSpec -import java.io.File -import java.io.FileInputStream -import java.io.FileNotFoundException -import java.io.FileOutputStream -import java.io.IOException -import java.nio.charset.StandardCharsets -import java.time.Year -import java.util.Objects -import javax.lang.model.element.Modifier - -// JavaPoet only supports line comments, and can't add a newline after file level comments. -val FILE_HEADER = """ - /* - * Copyright (C) ${Year.now().value} The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - // Generated by xmlpersistence. DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // @formatter:off -""".trimIndent() + "\n\n" - -private val atomicFileType = ClassName.get("android.util", "AtomicFile") - -fun generate(persistence: PersistenceInfo): JavaFile { - val distinctClassFields = persistence.root.allClassFields.distinctBy { it.type } - val type = TypeSpec.classBuilder(persistence.name) - .addJavadoc( - """ - Generated class implementing XML persistence for${'$'}W{@link $1T}. - <p> - This class provides atomicity for persistence via {@link $2T}, however it does not provide - thread safety, so please bring your own synchronization mechanism. - """.trimIndent(), persistence.root.type, atomicFileType - ) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addField(generateFileField()) - .addMethod(generateConstructor()) - .addMethod(generateReadMethod(persistence.root)) - .addMethod(generateParseMethod(persistence.root)) - .addMethods(distinctClassFields.map { generateParseClassMethod(it) }) - .addMethod(generateWriteMethod(persistence.root)) - .addMethod(generateSerializeMethod(persistence.root)) - .addMethods(distinctClassFields.map { generateSerializeClassMethod(it) }) - .addMethod(generateDeleteMethod()) - .build() - return JavaFile.builder(persistence.root.type.packageName(), type) - .skipJavaLangImports(true) - .indent(" ") - .build() -} - -private val nonNullType = ClassName.get("android.annotation", "NonNull") - -private fun generateFileField(): FieldSpec = - FieldSpec.builder(atomicFileType, "mFile", Modifier.PRIVATE, Modifier.FINAL) - .addAnnotation(nonNullType) - .build() - -private fun generateConstructor(): MethodSpec = - MethodSpec.constructorBuilder() - .addJavadoc( - """ - Create an instance of this class. - - @param file the XML file for persistence - """.trimIndent() - ) - .addModifiers(Modifier.PUBLIC) - .addParameter( - ParameterSpec.builder(File::class.java, "file").addAnnotation(nonNullType).build() - ) - .addStatement("mFile = new \$1T(file)", atomicFileType) - .build() - -private val nullableType = ClassName.get("android.annotation", "Nullable") - -private val xmlPullParserType = ClassName.get("org.xmlpull.v1", "XmlPullParser") - -private val xmlType = ClassName.get("android.util", "Xml") - -private val xmlPullParserExceptionType = ClassName.get("org.xmlpull.v1", "XmlPullParserException") - -private fun generateReadMethod(rootField: ClassFieldInfo): MethodSpec = - MethodSpec.methodBuilder("read") - .addJavadoc( - """ - Read${'$'}W{@link $1T}${'$'}Wfrom${'$'}Wthe${'$'}WXML${'$'}Wfile. - - @return the persisted${'$'}W{@link $1T},${'$'}Wor${'$'}W{@code null}${'$'}Wif${'$'}Wthe${'$'}WXML${'$'}Wfile${'$'}Wdoesn't${'$'}Wexist - @throws IllegalArgumentException if an error occurred while reading - """.trimIndent(), rootField.type - ) - .addAnnotation(nullableType) - .addModifiers(Modifier.PUBLIC) - .returns(rootField.type) - .addControlFlow("try (\$1T inputStream = mFile.openRead())", FileInputStream::class.java) { - addStatement("final \$1T parser = \$2T.newPullParser()", xmlPullParserType, xmlType) - addStatement("parser.setInput(inputStream, null)") - addStatement("return parse(parser)") - nextControlFlow("catch (\$1T e)", FileNotFoundException::class.java) - addStatement("return null") - nextControlFlow( - "catch (\$1T | \$2T e)", IOException::class.java, xmlPullParserExceptionType - ) - addStatement("throw new IllegalArgumentException(e)") - } - .build() - -private val ClassFieldInfo.allClassFields: List<ClassFieldInfo> - get() = - mutableListOf<ClassFieldInfo>().apply { - this += this@allClassFields - for (field in fields) { - when (field) { - is ClassFieldInfo -> this += field.allClassFields - is ListFieldInfo -> this += field.element.allClassFields - else -> {} - } - } - } - -private fun generateParseMethod(rootField: ClassFieldInfo): MethodSpec = - MethodSpec.methodBuilder("parse") - .addAnnotation(nonNullType) - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .returns(rootField.type) - .addParameter( - ParameterSpec.builder(xmlPullParserType, "parser").addAnnotation(nonNullType).build() - ) - .addExceptions(listOf(ClassName.get(IOException::class.java), xmlPullParserExceptionType)) - .apply { - addStatement("int type") - addStatement("int depth") - addStatement("int innerDepth = parser.getDepth() + 1") - addControlFlow( - "while ((type = parser.next()) != \$1T.END_DOCUMENT\$W" - + "&& ((depth = parser.getDepth()) >= innerDepth || type != \$1T.END_TAG))", - xmlPullParserType - ) { - addControlFlow( - "if (depth > innerDepth || type != \$1T.START_TAG)", xmlPullParserType - ) { - addStatement("continue") - } - addControlFlow( - "if (\$1T.equals(parser.getName(),\$W\$2S))", Objects::class.java, - rootField.tagName - ) { - addStatement("return \$1L(parser)", rootField.parseMethodName) - } - } - addStatement( - "throw new IllegalArgumentException(\$1S)", - "Missing root tag <${rootField.tagName}>" - ) - } - .build() - -private fun generateParseClassMethod(classField: ClassFieldInfo): MethodSpec = - MethodSpec.methodBuilder(classField.parseMethodName) - .addAnnotation(nonNullType) - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .returns(classField.type) - .addParameter( - ParameterSpec.builder(xmlPullParserType, "parser").addAnnotation(nonNullType).build() - ) - .apply { - val (attributeFields, tagFields) = classField.fields - .partition { it is PrimitiveFieldInfo || it is StringFieldInfo } - if (tagFields.isNotEmpty()) { - addExceptions( - listOf(ClassName.get(IOException::class.java), xmlPullParserExceptionType) - ) - } - val nameAllocator = NameAllocator().apply { - newName("parser") - newName("type") - newName("depth") - newName("innerDepth") - } - for (field in attributeFields) { - val variableName = nameAllocator.newName(field.variableName, field) - when (field) { - is PrimitiveFieldInfo -> { - val stringVariableName = - nameAllocator.newName("${field.variableName}String") - addStatement( - "final String \$1L =\$Wparser.getAttributeValue(null,\$W\$2S)", - stringVariableName, field.attributeName - ) - if (field.isRequired) { - addControlFlow("if (\$1L == null)", stringVariableName) { - addStatement( - "throw new IllegalArgumentException(\$1S)", - "Missing attribute \"${field.attributeName}\"" - ) - } - } - val boxedType = field.type.box() - val parseTypeMethodName = if (field.type.isPrimitive) { - "parse${field.type.toString().capitalize()}" - } else { - "valueOf" - } - if (field.isRequired) { - addStatement( - "final \$1T \$2L =\$W\$3T.\$4L($5L)", field.type, variableName, - boxedType, parseTypeMethodName, stringVariableName - ) - } else { - addStatement( - "final \$1T \$2L =\$W$3L != null ?\$W\$4T.\$5L($3L)\$W: null", - field.type, variableName, stringVariableName, boxedType, - parseTypeMethodName - ) - } - } - is StringFieldInfo -> - addStatement( - "final String \$1L =\$Wparser.getAttributeValue(null,\$W\$2S)", - variableName, field.attributeName - ) - else -> error(field) - } - } - if (tagFields.isNotEmpty()) { - for (field in tagFields) { - val variableName = nameAllocator.newName(field.variableName, field) - when (field) { - is ClassFieldInfo -> - addStatement("\$1T \$2L =\$Wnull", field.type, variableName) - is ListFieldInfo -> - addStatement( - "final \$1T \$2L =\$Wnew \$3T<>()", field.type, variableName, - ArrayList::class.java - ) - else -> error(field) - } - } - addStatement("int type") - addStatement("int depth") - addStatement("int innerDepth = parser.getDepth() + 1") - addControlFlow( - "while ((type = parser.next()) != \$1T.END_DOCUMENT\$W" - + "&& ((depth = parser.getDepth()) >= innerDepth || type != \$1T.END_TAG))", - xmlPullParserType - ) { - addControlFlow( - "if (depth > innerDepth || type != \$1T.START_TAG)", xmlPullParserType - ) { - addStatement("continue") - } - addControlFlow("switch (parser.getName())") { - for (field in tagFields) { - addControlFlow("case \$1S:", field.tagName) { - val variableName = nameAllocator.get(field) - when (field) { - is ClassFieldInfo -> { - addControlFlow("if (\$1L != null)", variableName) { - addStatement( - "throw new IllegalArgumentException(\$1S)", - "Duplicate tag \"${field.tagName}\"" - ) - } - addStatement( - "\$1L =\$W\$2L(parser)", variableName, - field.parseMethodName - ) - addStatement("break") - } - is ListFieldInfo -> { - val elementNameAllocator = nameAllocator.clone() - val elementVariableName = elementNameAllocator.newName( - field.element.xmlName!!.toLowerCamelCase() - ) - addStatement( - "final \$1T \$2L =\$W\$3L(parser)", field.element.type, - elementVariableName, field.element.parseMethodName - ) - addStatement( - "\$1L.add(\$2L)", variableName, elementVariableName - ) - addStatement("break") - } - else -> error(field) - } - } - } - } - } - } - for (field in tagFields.filter { it is ClassFieldInfo && it.isRequired }) { - addControlFlow("if ($1L == null)", nameAllocator.get(field)) { - addStatement( - "throw new IllegalArgumentException(\$1S)", "Missing tag <${field.tagName}>" - ) - } - } - addStatement( - classField.fields.joinToString(",\$W", "return new \$1T(", ")") { - nameAllocator.get(it) - }, classField.type - ) - } - .build() - -private val ClassFieldInfo.parseMethodName: String - get() = "parse${type.simpleName().toUpperCamelCase()}" - -private val xmlSerializerType = ClassName.get("org.xmlpull.v1", "XmlSerializer") - -private fun generateWriteMethod(rootField: ClassFieldInfo): MethodSpec = - MethodSpec.methodBuilder("write") - .apply { - val nameAllocator = NameAllocator().apply { - newName("outputStream") - newName("serializer") - } - val parameterName = nameAllocator.newName(rootField.variableName) - addJavadoc( - """ - Write${'$'}W{@link $1T}${'$'}Wto${'$'}Wthe${'$'}WXML${'$'}Wfile. - - @param $2L the${'$'}W{@link ${'$'}1T}${'$'}Wto${'$'}Wpersist - """.trimIndent(), rootField.type, parameterName - ) - addAnnotation(nullableType) - addModifiers(Modifier.PUBLIC) - addParameter( - ParameterSpec.builder(rootField.type, parameterName) - .addAnnotation(nonNullType) - .build() - ) - addStatement("\$1T outputStream = null", FileOutputStream::class.java) - addControlFlow("try") { - addStatement("outputStream = mFile.startWrite()") - addStatement( - "final \$1T serializer =\$W\$2T.newSerializer()", xmlSerializerType, xmlType - ) - addStatement( - "serializer.setOutput(outputStream, \$1T.UTF_8.name())", - StandardCharsets::class.java - ) - addStatement( - "serializer.setFeature(\$1S, true)", - "http://xmlpull.org/v1/doc/features.html#indent-output" - ) - addStatement("serializer.startDocument(null, true)") - addStatement("serialize(serializer,\$W\$1L)", parameterName) - addStatement("serializer.endDocument()") - addStatement("mFile.finishWrite(outputStream)") - nextControlFlow("catch (Exception e)") - addStatement("e.printStackTrace()") - addStatement("mFile.failWrite(outputStream)") - } - } - .build() - -private fun generateSerializeMethod(rootField: ClassFieldInfo): MethodSpec = - MethodSpec.methodBuilder("serialize") - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .addParameter( - ParameterSpec.builder(xmlSerializerType, "serializer") - .addAnnotation(nonNullType) - .build() - ) - .apply { - val nameAllocator = NameAllocator().apply { newName("serializer") } - val parameterName = nameAllocator.newName(rootField.variableName) - addParameter( - ParameterSpec.builder(rootField.type, parameterName) - .addAnnotation(nonNullType) - .build() - ) - addException(IOException::class.java) - addStatement("serializer.startTag(null, \$1S)", rootField.tagName) - addStatement("\$1L(serializer, \$2L)", rootField.serializeMethodName, parameterName) - addStatement("serializer.endTag(null, \$1S)", rootField.tagName) - } - .build() - -private fun generateSerializeClassMethod(classField: ClassFieldInfo): MethodSpec = - MethodSpec.methodBuilder(classField.serializeMethodName) - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .addParameter( - ParameterSpec.builder(xmlSerializerType, "serializer") - .addAnnotation(nonNullType) - .build() - ) - .apply { - val nameAllocator = NameAllocator().apply { - newName("serializer") - newName("i") - } - val parameterName = nameAllocator.newName(classField.serializeParameterName) - addParameter( - ParameterSpec.builder(classField.type, parameterName) - .addAnnotation(nonNullType) - .build() - ) - addException(IOException::class.java) - val (attributeFields, tagFields) = classField.fields - .partition { it is PrimitiveFieldInfo || it is StringFieldInfo } - for (field in attributeFields) { - val variableName = "$parameterName.${field.name}" - if (!field.isRequired) { - beginControlFlow("if (\$1L != null)", variableName) - } - when (field) { - is PrimitiveFieldInfo -> { - if (field.isRequired && !field.type.isPrimitive) { - addControlFlow("if (\$1L == null)", variableName) { - addStatement( - "throw new IllegalArgumentException(\$1S)", - "Field \"${field.name}\" is null" - ) - } - } - val stringVariableName = - nameAllocator.newName("${field.variableName}String") - addStatement( - "final String \$1L =\$WString.valueOf(\$2L)", stringVariableName, - variableName - ) - addStatement( - "serializer.attribute(null, \$1S, \$2L)", field.attributeName, - stringVariableName - ) - } - is StringFieldInfo -> { - if (field.isRequired) { - addControlFlow("if (\$1L == null)", variableName) { - addStatement( - "throw new IllegalArgumentException(\$1S)", - "Field \"${field.name}\" is null" - ) - } - } - addStatement( - "serializer.attribute(null, \$1S, \$2L)", field.attributeName, - variableName - ) - } - else -> error(field) - } - if (!field.isRequired) { - endControlFlow() - } - } - for (field in tagFields) { - val variableName = "$parameterName.${field.name}" - if (field.isRequired) { - addControlFlow("if (\$1L == null)", variableName) { - addStatement( - "throw new IllegalArgumentException(\$1S)", - "Field \"${field.name}\" is null" - ) - } - } - when (field) { - is ClassFieldInfo -> { - addStatement("serializer.startTag(null, \$1S)", field.tagName) - addStatement( - "\$1L(serializer, \$2L)", field.serializeMethodName, variableName - ) - addStatement("serializer.endTag(null, \$1S)", field.tagName) - } - is ListFieldInfo -> { - val sizeVariableName = nameAllocator.newName("${field.variableName}Size") - addStatement( - "final int \$1L =\$W\$2L.size()", sizeVariableName, variableName - ) - addControlFlow("for (int i = 0;\$Wi < \$1L;\$Wi++)", sizeVariableName) { - val elementNameAllocator = nameAllocator.clone() - val elementVariableName = elementNameAllocator.newName( - field.element.xmlName!!.toLowerCamelCase() - ) - addStatement( - "final \$1T \$2L =\$W\$3L.get(i)", field.element.type, - elementVariableName, variableName - ) - addControlFlow("if (\$1L == null)", elementVariableName) { - addStatement( - "throw new IllegalArgumentException(\$1S\$W+ i\$W+ \$2S)", - "Field element \"${field.name}[", "]\" is null" - ) - } - addStatement("serializer.startTag(null, \$1S)", field.element.tagName) - addStatement( - "\$1L(serializer,\$W\$2L)", field.element.serializeMethodName, - elementVariableName - ) - addStatement("serializer.endTag(null, \$1S)", field.element.tagName) - } - } - else -> error(field) - } - } - } - .build() - -private val ClassFieldInfo.serializeMethodName: String - get() = "serialize${type.simpleName().toUpperCamelCase()}" - -private val ClassFieldInfo.serializeParameterName: String - get() = type.simpleName().toLowerCamelCase() - -private val FieldInfo.variableName: String - get() = name.toLowerCamelCase() - -private val FieldInfo.attributeName: String - get() { - check(this is PrimitiveFieldInfo || this is StringFieldInfo) - return xmlNameOrName.toLowerCamelCase() - } - -private val FieldInfo.tagName: String - get() { - check(this is ClassFieldInfo || this is ListFieldInfo) - return xmlNameOrName.toLowerKebabCase() - } - -private val FieldInfo.xmlNameOrName: String - get() = xmlName ?: name - -private fun generateDeleteMethod(): MethodSpec = - MethodSpec.methodBuilder("delete") - .addJavadoc("Delete the XML file, if any.") - .addModifiers(Modifier.PUBLIC) - .addStatement("mFile.delete()") - .build() - -private inline fun MethodSpec.Builder.addControlFlow( - controlFlow: String, - vararg args: Any, - block: MethodSpec.Builder.() -> Unit -): MethodSpec.Builder { - beginControlFlow(controlFlow, *args) - block() - endControlFlow() - return this -} diff --git a/tools/xmlpersistence/src/main/kotlin/Main.kt b/tools/xmlpersistence/src/main/kotlin/Main.kt deleted file mode 100644 index e271f8cb9361..000000000000 --- a/tools/xmlpersistence/src/main/kotlin/Main.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.File -import java.nio.file.Files - -fun main(args: Array<String>) { - val showUsage = args.isEmpty() || when (args.singleOrNull()) { - "-h", "--help" -> true - else -> false - } - if (showUsage) { - usage() - return - } - - val files = args.flatMap { - File(it).walk().filter { it.isFile && it.extension == "java" }.map { it.toPath() } - } - val persistences = parse(files) - for (persistence in persistences) { - val file = generate(persistence) - Files.newBufferedWriter(persistence.path).use { - it.write(FILE_HEADER) - file.writeTo(it) - } - } -} - -private fun usage() { - println("Usage: xmlpersistence <FILES>") -} diff --git a/tools/xmlpersistence/src/main/kotlin/Parser.kt b/tools/xmlpersistence/src/main/kotlin/Parser.kt deleted file mode 100644 index 3ea12a9aa389..000000000000 --- a/tools/xmlpersistence/src/main/kotlin/Parser.kt +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.github.javaparser.JavaParser -import com.github.javaparser.ParseProblemException -import com.github.javaparser.ParseResult -import com.github.javaparser.ParserConfiguration -import com.github.javaparser.ast.Node -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration -import com.github.javaparser.ast.body.FieldDeclaration -import com.github.javaparser.ast.body.TypeDeclaration -import com.github.javaparser.ast.expr.AnnotationExpr -import com.github.javaparser.ast.expr.Expression -import com.github.javaparser.ast.expr.NormalAnnotationExpr -import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr -import com.github.javaparser.ast.expr.StringLiteralExpr -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration -import com.github.javaparser.resolution.types.ResolvedPrimitiveType -import com.github.javaparser.resolution.types.ResolvedReferenceType -import com.github.javaparser.symbolsolver.JavaSymbolSolver -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration -import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver -import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver -import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver -import com.squareup.javapoet.ClassName -import com.squareup.javapoet.ParameterizedTypeName -import com.squareup.javapoet.TypeName -import java.nio.file.Path -import java.util.Optional - -class PersistenceInfo( - val name: String, - val root: ClassFieldInfo, - val path: Path -) - -sealed class FieldInfo { - abstract val name: String - abstract val xmlName: String? - abstract val type: TypeName - abstract val isRequired: Boolean -} - -class PrimitiveFieldInfo( - override val name: String, - override val xmlName: String?, - override val type: TypeName, - override val isRequired: Boolean -) : FieldInfo() - -class StringFieldInfo( - override val name: String, - override val xmlName: String?, - override val isRequired: Boolean -) : FieldInfo() { - override val type: TypeName = ClassName.get(String::class.java) -} - -class ClassFieldInfo( - override val name: String, - override val xmlName: String?, - override val type: ClassName, - override val isRequired: Boolean, - val fields: List<FieldInfo> -) : FieldInfo() - -class ListFieldInfo( - override val name: String, - override val xmlName: String?, - override val type: ParameterizedTypeName, - val element: ClassFieldInfo -) : FieldInfo() { - override val isRequired: Boolean = true -} - -fun parse(files: List<Path>): List<PersistenceInfo> { - val typeSolver = CombinedTypeSolver().apply { add(ReflectionTypeSolver()) } - val javaParser = JavaParser(ParserConfiguration() - .setSymbolResolver(JavaSymbolSolver(typeSolver))) - val compilationUnits = files.map { javaParser.parse(it).getOrThrow() } - val memoryTypeSolver = MemoryTypeSolver().apply { - for (compilationUnit in compilationUnits) { - for (typeDeclaration in compilationUnit.getNodesByClass<TypeDeclaration<*>>()) { - val name = typeDeclaration.fullyQualifiedName.getOrNull() ?: continue - addDeclaration(name, typeDeclaration.resolve()) - } - } - } - typeSolver.add(memoryTypeSolver) - return mutableListOf<PersistenceInfo>().apply { - for (compilationUnit in compilationUnits) { - val classDeclarations = compilationUnit - .getNodesByClass<ClassOrInterfaceDeclaration>() - .filter { !it.isInterface && (!it.isNestedType || it.isStatic) } - this += classDeclarations.mapNotNull { parsePersistenceInfo(it) } - } - } -} - -private fun parsePersistenceInfo(classDeclaration: ClassOrInterfaceDeclaration): PersistenceInfo? { - val annotation = classDeclaration.getAnnotationByName("XmlPersistence").getOrNull() - ?: return null - val rootClassName = classDeclaration.nameAsString - val name = annotation.getMemberValue("value")?.stringLiteralValue - ?: "${rootClassName}Persistence" - val rootXmlName = classDeclaration.getAnnotationByName("XmlName").getOrNull() - ?.getMemberValue("value")?.stringLiteralValue - val root = parseClassFieldInfo( - rootXmlName ?: rootClassName, rootXmlName, true, classDeclaration - ) - val path = classDeclaration.findCompilationUnit().get().storage.get().path - .resolveSibling("$name.java") - return PersistenceInfo(name, root, path) -} - -private fun parseClassFieldInfo( - name: String, - xmlName: String?, - isRequired: Boolean, - classDeclaration: ClassOrInterfaceDeclaration -): ClassFieldInfo { - val fields = classDeclaration.fields.filterNot { it.isStatic }.map { parseFieldInfo(it) } - val type = classDeclaration.resolve().typeName - return ClassFieldInfo(name, xmlName, type, isRequired, fields) -} - -private fun parseFieldInfo(field: FieldDeclaration): FieldInfo { - require(field.isPublic && field.isFinal) - val variable = field.variables.single() - val name = variable.nameAsString - val annotations = field.annotations + variable.type.annotations - val annotation = annotations.getByName("XmlName") - val xmlName = annotation?.getMemberValue("value")?.stringLiteralValue - val isRequired = annotations.getByName("NonNull") != null - return when (val type = variable.type.resolve()) { - is ResolvedPrimitiveType -> { - val primitiveType = type.typeName - PrimitiveFieldInfo(name, xmlName, primitiveType, true) - } - is ResolvedReferenceType -> { - when (type.qualifiedName) { - Boolean::class.javaObjectType.name, Byte::class.javaObjectType.name, - Short::class.javaObjectType.name, Char::class.javaObjectType.name, - Integer::class.javaObjectType.name, Long::class.javaObjectType.name, - Float::class.javaObjectType.name, Double::class.javaObjectType.name -> - PrimitiveFieldInfo(name, xmlName, type.typeName, isRequired) - String::class.java.name -> StringFieldInfo(name, xmlName, isRequired) - List::class.java.name -> { - requireNotNull(xmlName) - val elementType = type.typeParametersValues().single() - require(elementType is ResolvedReferenceType) - val listType = ParameterizedTypeName.get( - ClassName.get(List::class.java), elementType.typeName - ) - val element = parseClassFieldInfo( - "(element)", xmlName, true, elementType.classDeclaration - ) - ListFieldInfo(name, xmlName, listType, element) - } - else -> parseClassFieldInfo(name, xmlName, isRequired, type.classDeclaration) - } - } - else -> error(type) - } -} - -private fun <T> ParseResult<T>.getOrThrow(): T = - if (isSuccessful) { - result.get() - } else { - throw ParseProblemException(problems) - } - -private inline fun <reified T : Node> Node.getNodesByClass(): List<T> = - getNodesByClass(T::class.java) - -private fun <T : Node> Node.getNodesByClass(klass: Class<T>): List<T> = mutableListOf<T>().apply { - if (klass.isInstance(this@getNodesByClass)) { - this += klass.cast(this@getNodesByClass) - } - for (childNode in childNodes) { - this += childNode.getNodesByClass(klass) - } -} - -private fun <T> Optional<T>.getOrNull(): T? = orElse(null) - -private fun List<AnnotationExpr>.getByName(name: String): AnnotationExpr? = - find { it.name.identifier == name } - -private fun AnnotationExpr.getMemberValue(name: String): Expression? = - when (this) { - is NormalAnnotationExpr -> pairs.find { it.nameAsString == name }?.value - is SingleMemberAnnotationExpr -> if (name == "value") memberValue else null - else -> null - } - -private val Expression.stringLiteralValue: String - get() { - require(this is StringLiteralExpr) - return value - } - -private val ResolvedReferenceType.classDeclaration: ClassOrInterfaceDeclaration - get() { - val resolvedClassDeclaration = typeDeclaration - require(resolvedClassDeclaration is JavaParserClassDeclaration) - return resolvedClassDeclaration.wrappedNode - } - -private val ResolvedPrimitiveType.typeName: TypeName - get() = - when (this) { - ResolvedPrimitiveType.BOOLEAN -> TypeName.BOOLEAN - ResolvedPrimitiveType.BYTE -> TypeName.BYTE - ResolvedPrimitiveType.SHORT -> TypeName.SHORT - ResolvedPrimitiveType.CHAR -> TypeName.CHAR - ResolvedPrimitiveType.INT -> TypeName.INT - ResolvedPrimitiveType.LONG -> TypeName.LONG - ResolvedPrimitiveType.FLOAT -> TypeName.FLOAT - ResolvedPrimitiveType.DOUBLE -> TypeName.DOUBLE - } - -// This doesn't support type parameters. -private val ResolvedReferenceType.typeName: TypeName - get() = typeDeclaration.typeName - -private val ResolvedReferenceTypeDeclaration.typeName: ClassName - get() { - val packageName = packageName - val classNames = className.split(".") - val topLevelClassName = classNames.first() - val nestedClassNames = classNames.drop(1) - return ClassName.get(packageName, topLevelClassName, *nestedClassNames.toTypedArray()) - } diff --git a/tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt b/tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt deleted file mode 100644 index b4bdbba7170b..000000000000 --- a/tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Locale - -private val camelHumpBoundary = Regex( - "-" - + "|_" - + "|(?<=[0-9])(?=[^0-9])" - + "|(?<=[A-Z])(?=[^A-Za-z]|[A-Z][a-z])" - + "|(?<=[a-z])(?=[^a-z])" -) - -private fun String.toCamelHumps(): List<String> = split(camelHumpBoundary) - -fun String.toUpperCamelCase(): String = - toCamelHumps().joinToString("") { it.toLowerCase(Locale.ROOT).capitalize(Locale.ROOT) } - -fun String.toLowerCamelCase(): String = toUpperCamelCase().decapitalize(Locale.ROOT) - -fun String.toUpperKebabCase(): String = - toCamelHumps().joinToString("-") { it.toUpperCase(Locale.ROOT) } - -fun String.toLowerKebabCase(): String = - toCamelHumps().joinToString("-") { it.toLowerCase(Locale.ROOT) } - -fun String.toUpperSnakeCase(): String = - toCamelHumps().joinToString("_") { it.toUpperCase(Locale.ROOT) } - -fun String.toLowerSnakeCase(): String = - toCamelHumps().joinToString("_") { it.toLowerCase(Locale.ROOT) } |