X-Git-Url: https://git.saurik.com/android/aapt.git/blobdiff_plain/d81652a8a555152c6524211dd1c34ea59d5d9181..40b7bac653fa2b644f6d65444a546b8fe176ca3d:/Resource.cpp diff --git a/Resource.cpp b/Resource.cpp index c0fe538..a69adc1 100644 --- a/Resource.cpp +++ b/Resource.cpp @@ -14,6 +14,8 @@ #include "FileFinder.h" #include "CacheUpdater.h" +#include + #if HAVE_PRINTF_ZD # define ZD "%zd" # define ZD_TYPE ssize_t @@ -24,6 +26,9 @@ #define NOISY(x) // x +// Number of threads to use for preprocessing images. +static const size_t MAX_THREADS = 4; + // ========================================================================== // ========================================================================== // ========================================================================== @@ -302,21 +307,52 @@ static status_t makeFileResources(Bundle* bundle, const sp& assets, return hasErrors ? UNKNOWN_ERROR : NO_ERROR; } -static status_t preProcessImages(Bundle* bundle, const sp& assets, +class PreProcessImageWorkUnit : public WorkQueue::WorkUnit { +public: + PreProcessImageWorkUnit(const Bundle* bundle, const sp& assets, + const sp& file, volatile bool* hasErrors) : + mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) { + } + + virtual bool run() { + status_t status = preProcessImage(mBundle, mAssets, mFile, NULL); + if (status) { + *mHasErrors = true; + } + return true; // continue even if there are errors + } + +private: + const Bundle* mBundle; + sp mAssets; + sp mFile; + volatile bool* mHasErrors; +}; + +static status_t preProcessImages(const Bundle* bundle, const sp& assets, const sp& set, const char* type) { - bool hasErrors = false; + volatile bool hasErrors = false; ssize_t res = NO_ERROR; if (bundle->getUseCrunchCache() == false) { + WorkQueue wq(MAX_THREADS, false); ResourceDirIterator it(set, String8(type)); - Vector > newNameFiles; - Vector newNamePaths; while ((res=it.next()) == NO_ERROR) { - res = preProcessImage(bundle, assets, it.getFile(), NULL); - if (res < NO_ERROR) { + PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit( + bundle, assets, it.getFile(), &hasErrors); + status_t status = wq.schedule(w); + if (status) { + fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status); hasErrors = true; + delete w; + break; } } + status_t status = wq.finish(); + if (status) { + fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status); + hasErrors = true; + } } return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR; } @@ -1808,7 +1844,7 @@ static status_t writeSymbolClass( if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { continue; } - if (!includePrivate && !sym.isPublic) { + if (!assets->isJavaSymbol(sym, includePrivate)) { continue; } String16 name(sym.name); @@ -1864,7 +1900,7 @@ static status_t writeSymbolClass( if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) { continue; } - if (!includePrivate && !sym.isPublic) { + if (!assets->isJavaSymbol(sym, includePrivate)) { continue; } String16 name(sym.name); @@ -1976,7 +2012,8 @@ status_t writeResourceSymbols(Bundle* bundle, const sp& assets, "\n" "package %s;\n\n", package.string()); - status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0, bundle->getNonConstantId()); + status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, + className, 0, bundle->getNonConstantId()); if (err != NO_ERROR) { return err; } @@ -2052,6 +2089,23 @@ addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName, keep->add(rule, location); } +void +addProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName, + const char* pkg, const String8& srcName, int line) +{ + String8 rule("-keepclassmembers class * { *** "); + rule += memberName; + rule += "(...); }"; + + String8 location("onClick "); + location += srcName; + char lineno[20]; + sprintf(lineno, ":%d", line); + location += lineno; + + keep->add(rule, location); +} + status_t writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp& assets) { @@ -2214,6 +2268,13 @@ writeProguardForXml(ProguardKeepSet* keep, const sp& layoutFile, } } } + ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick"); + if (attrIndex >= 0) { + size_t len; + addProguardKeepMethodRule(keep, + String8(tree.getAttributeStringValue(attrIndex, &len)), NULL, + layoutFile->getPrintableSource(), tree.getLineNumber()); + } } return NO_ERROR; @@ -2252,6 +2313,9 @@ writeProguardForLayouts(ProguardKeepSet* keep, const sp& assets) } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) { startTag = "PreferenceScreen"; tagAttrPairs = &kXmlTagAttrPairs; + } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) { + startTag = "menu"; + tagAttrPairs = NULL; } else { continue; }